[clang] a68d20e - [clang] Implement CWG2428 "Deprecating a concept" (#92295)
via cfe-commits
cfe-commits at lists.llvm.org
Fri May 17 05:02:48 PDT 2024
Author: Vlad Serebrennikov
Date: 2024-05-17T16:02:44+04:00
New Revision: a68d20e986053ec571223a9f3ead3e146a27dc82
URL: https://github.com/llvm/llvm-project/commit/a68d20e986053ec571223a9f3ead3e146a27dc82
DIFF: https://github.com/llvm/llvm-project/commit/a68d20e986053ec571223a9f3ead3e146a27dc82.diff
LOG: [clang] Implement CWG2428 "Deprecating a concept" (#92295)
This patch allows attributes to be attached to C++20 concepts,
implementing
[CWG2428](https://cplusplus.github.io/CWG/issues/2428.html).
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/include/clang/Sema/Sema.h
clang/lib/Parse/ParseTemplate.cpp
clang/lib/Sema/SemaChecking.cpp
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaTemplate.cpp
clang/lib/Sema/SemaType.cpp
clang/test/CXX/drs/cwg24xx.cpp
clang/test/SemaCXX/cxx-deprecated.cpp
clang/www/cxx_dr_status.html
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 65d191b6161a4..40e41c940b6af 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -226,6 +226,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/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 873592a2d430a..226987b975700 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(const AutoType *AutoT, SourceLocation Loc);
+
private:
void CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
const ArraySubscriptExpr *ASE = nullptr,
@@ -9356,7 +9358,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..8f841be422dd8 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -167,9 +167,13 @@ 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);
+ // We need to explicitly pass ConceptDecl to ParsingDeclRAIIObject, so that
+ // delayed diagnostics (e.g. warn_deprecated) have a Decl to work with.
+ ParsingTemplateParams.complete(ConceptDecl);
+ return Actions.ConvertDeclToDeclGroup(ConceptDecl);
+ }
return ParseDeclarationAfterTemplate(
Context, TemplateInfo, ParsingTemplateParams, DeclEnd, AccessAttrs, AS);
@@ -316,7 +320,8 @@ Parser::ParseConceptDefinition(const ParsedTemplateInfo &TemplateInfo,
const IdentifierInfo *Id = Result.Identifier;
SourceLocation IdLoc = Result.getBeginLoc();
- DiagnoseAndSkipCXX11Attributes();
+ ParsedAttributes Attrs(AttrFactory);
+ MaybeParseAttributes(PAKM_GNU | PAKM_CXX11, Attrs);
if (!TryConsumeToken(tok::equal)) {
Diag(Tok.getLocation(), diag::err_expected) << tok::equal;
@@ -335,8 +340,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/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index ecd1821651140..f2dc8e9dd0050 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -8092,6 +8092,12 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
diagnoseArgDependentDiagnoseIfAttrs(FD, ThisArg, Args, Loc);
}
+void Sema::CheckConstrainedAuto(const AutoType *AutoT, SourceLocation Loc) {
+ if (ConceptDecl *Decl = AutoT->getTypeConstraintConcept()) {
+ DiagnoseUseOfDecl(Decl, Loc);
+ }
+}
+
/// 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 0dbdf923df95a..bb0bee0d234c5 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -7573,6 +7573,11 @@ NamedDecl *Sema::ActOnVariableDeclarator(
tryToFixVariablyModifiedVarType(TInfo, R, D.getIdentifierLoc(),
/*DiagID=*/0);
+ if (const AutoType *AutoT = R->getAs<AutoType>())
+ CheckConstrainedAuto(
+ AutoT,
+ TInfo->getTypeLoc().getContainedAutoTypeLoc().getConceptNameLoc());
+
bool IsMemberSpecialization = false;
bool IsVariableTemplateSpecialization = false;
bool IsPartialSpecialization = false;
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 1b3f1e8bf80f4..0462d3520037f 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -5653,6 +5653,8 @@ Sema::CheckConceptTemplateId(const CXXScopeSpec &SS,
/*UpdateArgsWithConversions=*/false))
return ExprError();
+ DiagnoseUseOfDecl(NamedConcept, ConceptNameInfo.getLoc());
+
auto *CSD = ImplicitConceptSpecializationDecl::Create(
Context, NamedConcept->getDeclContext(), NamedConcept->getLocation(),
CanonicalConverted);
@@ -9859,7 +9861,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()) {
@@ -9921,6 +9924,9 @@ Decl *Sema::ActOnConceptDefinition(
ActOnDocumentableDecl(NewDecl);
if (AddToScope)
PushOnScopeChains(NewDecl, S);
+
+ ProcessDeclAttributeList(S, NewDecl, Attrs);
+
return NewDecl;
}
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 9c002d56b5bd9..c19c8cc34dd3b 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -6392,6 +6392,11 @@ TypeResult Sema::ActOnTypeName(Declarator &D) {
CheckExtraCXXDefaultArguments(D);
}
+ if (const AutoType *AutoT = T->getAs<AutoType>())
+ CheckConstrainedAuto(
+ AutoT,
+ 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 75e1a614765c5..4c7b1506e86ea 100644
--- a/clang/test/CXX/drs/cwg24xx.cpp
+++ b/clang/test/CXX/drs/cwg24xx.cpp
@@ -45,6 +45,48 @@ void fallthrough(int n) {
#endif
}
+namespace cwg2428 { // cwg2428: 19
+#if __cplusplus >= 202002L
+template <typename>
+concept C [[deprecated]] = true; // #cwg2428-C
+
+template <typename>
+[[deprecated]] concept C2 = true;
+// expected-error at -1 {{expected unqualified-id}}
+
+template <typename T>
+concept C3 = C<T>;
+// expected-warning at -1 {{'C' is deprecated}}
+// expected-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}}
+
+template <typename T, C U>
+// expected-warning at -1 {{'C' is deprecated}}
+// expected-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}}
+requires C<T>
+// expected-warning at -1 {{'C' is deprecated}}
+// expected-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}}
+void f() {
+ bool b = C<int>;
+ // expected-warning at -1 {{'C' is deprecated}}
+ // expected-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}}
+};
+
+void g(C auto a) {};
+// expected-warning at -1 {{'C' is deprecated}}
+// expected-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}}
+
+template <typename T>
+auto h() -> C auto {
+// expected-warning at -1 {{'C' is deprecated}}
+// expected-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}}
+ C auto foo = T();
+ // expected-warning at -1 {{'C' is deprecated}}
+ // expected-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}}
+ return foo;
+}
+#endif
+} // namespace cwg2428
+
namespace cwg2430 { // cwg2430: 2.7
struct S {
S f(S s) { return s; }
diff --git a/clang/test/SemaCXX/cxx-deprecated.cpp b/clang/test/SemaCXX/cxx-deprecated.cpp
index aa4501d53197a..81eb07608300d 100644
--- a/clang/test/SemaCXX/cxx-deprecated.cpp
+++ b/clang/test/SemaCXX/cxx-deprecated.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
namespace [[deprecated]] {} // expected-warning {{'deprecated' attribute on anonymous namespace ignored}}
@@ -27,3 +27,13 @@ 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 at -1 {{'C' is deprecated}}
+// expected-note@#C {{'C' has been explicitly marked deprecated here}}
+void f();
+} // namespace cxx20_concept
diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html
index 2ed79fa21db26..5d517d358672c 100755
--- a/clang/www/cxx_dr_status.html
+++ b/clang/www/cxx_dr_status.html
@@ -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>
More information about the cfe-commits
mailing list