[clang] [Clang] Implement CWG 2707 "Deduction guides cannot have a trailing requires-clause" (PR #110473)
Younan Zhang via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 30 02:05:25 PDT 2024
https://github.com/zyn0217 created https://github.com/llvm/llvm-project/pull/110473
Closes https://github.com/llvm/llvm-project/issues/98595
>From 0a0654909088b11eb360835999d67cc9d633ef91 Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Mon, 30 Sep 2024 16:57:14 +0800
Subject: [PATCH] [Clang] Implement CWG 2707 "Deduction guides cannot have a
trailing requires-clause"
---
clang/docs/ReleaseNotes.rst | 3 ++
clang/include/clang/AST/DeclCXX.h | 9 ++++--
.../clang/Basic/DiagnosticSemaKinds.td | 2 --
clang/lib/AST/DeclCXX.cpp | 9 +++---
clang/lib/Sema/SemaDecl.cpp | 11 +++-----
.../lib/Sema/SemaTemplateInstantiateDecl.cpp | 2 +-
clang/test/CXX/dcl/dcl.decl/p3.cpp | 2 +-
clang/test/CXX/drs/cwg27xx.cpp | 28 +++++++++++++++++++
clang/www/cxx_dr_status.html | 4 +--
9 files changed, 50 insertions(+), 20 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 1fbcac807d0b30..34ff107ef6b124 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -202,6 +202,9 @@ Resolutions to C++ Defect Reports
- Reject explicit object parameters with type ``void`` (``this void``).
(`CWG2915: Explicit object parameters of type void <https://cplusplus.github.io/CWG/issues/2915.html>`_).
+- Clang now allows trailing requires clause on explicit deduction guides.
+ (`CWG2707: Deduction guides cannot have a trailing requires-clause <https://cplusplus.github.io/CWG/issues/2707.html>`_).
+
C Language Changes
------------------
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h
index 252e6e92564142..2693cc0e95b4b2 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -1965,9 +1965,11 @@ class CXXDeductionGuideDecl : public FunctionDecl {
ExplicitSpecifier ES,
const DeclarationNameInfo &NameInfo, QualType T,
TypeSourceInfo *TInfo, SourceLocation EndLocation,
- CXXConstructorDecl *Ctor, DeductionCandidate Kind)
+ CXXConstructorDecl *Ctor, DeductionCandidate Kind,
+ Expr *TrailingRequiresClause)
: FunctionDecl(CXXDeductionGuide, C, DC, StartLoc, NameInfo, T, TInfo,
- SC_None, false, false, ConstexprSpecKind::Unspecified),
+ SC_None, false, false, ConstexprSpecKind::Unspecified,
+ TrailingRequiresClause),
Ctor(Ctor), ExplicitSpec(ES) {
if (EndLocation.isValid())
setRangeEnd(EndLocation);
@@ -1987,7 +1989,8 @@ class CXXDeductionGuideDecl : public FunctionDecl {
ExplicitSpecifier ES, const DeclarationNameInfo &NameInfo, QualType T,
TypeSourceInfo *TInfo, SourceLocation EndLocation,
CXXConstructorDecl *Ctor = nullptr,
- DeductionCandidate Kind = DeductionCandidate::Normal);
+ DeductionCandidate Kind = DeductionCandidate::Normal,
+ Expr *TrailingRequiresClause = nullptr);
static CXXDeductionGuideDecl *CreateDeserialized(ASTContext &C,
GlobalDeclID ID);
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index f3d5d4c56606cc..93533000c76686 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3050,8 +3050,6 @@ def note_is_deducible_constraint_evaluated_to_false : Note<
"cannot deduce template arguments for %0 from %1">;
def err_constrained_virtual_method : Error<
"virtual function cannot have a requires clause">;
-def err_trailing_requires_clause_on_deduction_guide : Error<
- "deduction guide cannot have a requires clause">;
def err_constrained_non_templated_function
: Error<"non-templated function cannot have a requires clause">;
def err_non_temp_spec_requires_clause : Error<
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 01143391edab40..f5a0aa8f82512e 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -2211,9 +2211,10 @@ CXXDeductionGuideDecl *CXXDeductionGuideDecl::Create(
ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
ExplicitSpecifier ES, const DeclarationNameInfo &NameInfo, QualType T,
TypeSourceInfo *TInfo, SourceLocation EndLocation, CXXConstructorDecl *Ctor,
- DeductionCandidate Kind) {
- return new (C, DC) CXXDeductionGuideDecl(C, DC, StartLoc, ES, NameInfo, T,
- TInfo, EndLocation, Ctor, Kind);
+ DeductionCandidate Kind, Expr *TrailingRequiresClause) {
+ return new (C, DC)
+ CXXDeductionGuideDecl(C, DC, StartLoc, ES, NameInfo, T, TInfo,
+ EndLocation, Ctor, Kind, TrailingRequiresClause);
}
CXXDeductionGuideDecl *
@@ -2221,7 +2222,7 @@ CXXDeductionGuideDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
return new (C, ID) CXXDeductionGuideDecl(
C, nullptr, SourceLocation(), ExplicitSpecifier(), DeclarationNameInfo(),
QualType(), nullptr, SourceLocation(), nullptr,
- DeductionCandidate::Normal);
+ DeductionCandidate::Normal, nullptr);
}
RequiresExprBodyDecl *RequiresExprBodyDecl::Create(
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 1bf0e800a36228..0e536f71a2f70d 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -9293,15 +9293,12 @@ static FunctionDecl *CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
TrailingRequiresClause);
} else if (Name.getNameKind() == DeclarationName::CXXDeductionGuideName) {
- if (TrailingRequiresClause)
- SemaRef.Diag(TrailingRequiresClause->getBeginLoc(),
- diag::err_trailing_requires_clause_on_deduction_guide)
- << TrailingRequiresClause->getSourceRange();
if (SemaRef.CheckDeductionGuideDeclarator(D, R, SC))
return nullptr;
- return CXXDeductionGuideDecl::Create(SemaRef.Context, DC, D.getBeginLoc(),
- ExplicitSpecifier, NameInfo, R, TInfo,
- D.getEndLoc());
+ return CXXDeductionGuideDecl::Create(
+ SemaRef.Context, DC, D.getBeginLoc(), ExplicitSpecifier, NameInfo, R,
+ TInfo, D.getEndLoc(), /*Ctor=*/nullptr,
+ /*Kind=*/DeductionCandidate::Normal, TrailingRequiresClause);
} else if (DC->isRecord()) {
// If the name of the function is the same as the name of the record,
// then this must be an invalid constructor that has a return type.
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index c3cb9d5d8c2c3d..1c35c7d288e325 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -2233,7 +2233,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(
SemaRef.Context, DC, D->getInnerLocStart(),
InstantiatedExplicitSpecifier, NameInfo, T, TInfo,
D->getSourceRange().getEnd(), DGuide->getCorrespondingConstructor(),
- DGuide->getDeductionCandidateKind());
+ DGuide->getDeductionCandidateKind(), TrailingRequiresClause);
Function->setAccess(D->getAccess());
} else {
Function = FunctionDecl::Create(
diff --git a/clang/test/CXX/dcl/dcl.decl/p3.cpp b/clang/test/CXX/dcl/dcl.decl/p3.cpp
index f141568ba6c221..b082e1c122a09e 100644
--- a/clang/test/CXX/dcl/dcl.decl/p3.cpp
+++ b/clang/test/CXX/dcl/dcl.decl/p3.cpp
@@ -65,4 +65,4 @@ struct R {
};
template<typename T>
-R(T) -> R<T> requires true; // expected-error{{deduction guide cannot have a requires clause}}
+R(T) -> R<T> requires true;
diff --git a/clang/test/CXX/drs/cwg27xx.cpp b/clang/test/CXX/drs/cwg27xx.cpp
index 2b57dbc60aed70..6b3c75f08cd02c 100644
--- a/clang/test/CXX/drs/cwg27xx.cpp
+++ b/clang/test/CXX/drs/cwg27xx.cpp
@@ -201,3 +201,31 @@ static_assert(false, f().s);
#endif
} // namespace cwg2798
+namespace cwg2707 { // cwg2707: 20
+
+#if __cplusplus >= 202002L
+
+template <class T, unsigned N> struct A {
+ T value[N];
+};
+
+template <typename... T>
+A(T...) -> A<int, sizeof...(T)> requires (sizeof...(T) == 2);
+
+// Brace elision is not allowed for synthesized CTAD guides if the array size
+// is value-dependent.
+// So this should pick up our explicit deduction guide.
+A a = {1, 2};
+
+A b = {3, 4, 5};
+// expected-error at -1 {{no viable constructor or deduction guide}} \
+// expected-note at -12 {{candidate function template not viable}} \
+// expected-note at -12 {{implicit deduction guide}} \
+// expected-note at -7 {{constraints not satisfied}} \
+// expected-note at -7 {{because 'sizeof...(T) == 2' (3 == 2) evaluated to false}} \
+// expected-note at -12 {{candidate function template not viable}} \
+// expected-note at -12 {{implicit deduction guide}}
+
+#endif
+
+} // namespace cwg2707
diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html
index e5c5e50104fdaf..978351716ce33d 100755
--- a/clang/www/cxx_dr_status.html
+++ b/clang/www/cxx_dr_status.html
@@ -16089,7 +16089,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/2707.html">2707</a></td>
<td>DRWP</td>
<td>Deduction guides cannot have a trailing <I>requires-clause</I></td>
- <td class="unknown" align="center">Unknown</td>
+ <td class="unreleased" align="center">Clang 20</td>
</tr>
<tr id="2708">
<td><a href="https://cplusplus.github.io/CWG/issues/2708.html">2708</a></td>
@@ -17334,7 +17334,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/2913.html">2913</a></td>
<td>tentatively ready</td>
<td>Grammar for <I>deduction-guide</I> has <I>requires-clause</I> in the wrong position</td>
- <td align="center">Not resolved</td>
+ <td class="unreleased" align="center">Clang 20</td>
</tr>
<tr class="open" id="2914">
<td><a href="https://cplusplus.github.io/CWG/issues/2914.html">2914</a></td>
More information about the cfe-commits
mailing list