[clang] [Clang][Sema] Implement approved resolution for CWG2858 (PR #88042)
Krystian Stasiowski via cfe-commits
cfe-commits at lists.llvm.org
Tue Apr 9 08:58:05 PDT 2024
https://github.com/sdkrystian updated https://github.com/llvm/llvm-project/pull/88042
>From e850ae0982efbb7cec7c33d6b927844d89128743 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski <sdkrystian at gmail.com>
Date: Mon, 8 Apr 2024 09:46:08 -0400
Subject: [PATCH 1/5] [Clang][Sema] Implement approved resolution for CWG2858
---
clang/include/clang/Basic/DiagnosticSemaKinds.td | 7 +++----
clang/lib/Sema/SemaDecl.cpp | 13 ++++++-------
.../expr.prim.id/expr.prim.id.qual/p3.cpp | 16 ++++++++++++++++
3 files changed, 25 insertions(+), 11 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4fbbc42273ba93..2ce2013aac7362 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2402,10 +2402,6 @@ def err_selected_explicit_constructor : Error<
def note_explicit_ctor_deduction_guide_here : Note<
"explicit %select{constructor|deduction guide}0 declared here">;
-// C++11 decltype
-def err_decltype_in_declarator : Error<
- "'decltype' cannot be used to name a declaration">;
-
// C++11 auto
def warn_cxx98_compat_auto_type_specifier : Warning<
"'auto' type specifier is incompatible with C++98">,
@@ -8302,6 +8298,9 @@ def ext_template_after_declarative_nns : ExtWarn<
def ext_alias_template_in_declarative_nns : ExtWarn<
"a declarative nested name specifier cannot name an alias template">,
InGroup<DiagGroup<"alias-template-in-declaration-name">>;
+def err_computed_type_in_declarative_nns : Error<
+ "%select{a pack indexing type|'decltype'}0 cannot be used in "
+ "a declarative nested name specifier">;
def err_no_typeid_with_fno_rtti : Error<
"use of typeid requires -frtti">;
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index c790dab72dd721..1ba6b3beb1c758 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -6335,16 +6335,15 @@ bool Sema::diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,
if (TST->isDependentType() && TST->isTypeAlias())
Diag(Loc, diag::ext_alias_template_in_declarative_nns)
<< SpecLoc.getLocalSourceRange();
- } else if (T->isDecltypeType()) {
+ } else if (T->isDecltypeType() || T->getAsAdjusted<PackIndexingType>()) {
// C++23 [expr.prim.id.qual]p2:
// [...] A declarative nested-name-specifier shall not have a
- // decltype-specifier.
+ // computed-type-specifier.
//
- // FIXME: This wording appears to be defective as it does not forbid
- // declarative nested-name-specifiers with pack-index-specifiers.
- // See https://github.com/cplusplus/CWG/issues/499.
- Diag(Loc, diag::err_decltype_in_declarator)
- << SpecLoc.getTypeLoc().getSourceRange();
+ // CWG2858 changed this from 'decltype-specifier' to
+ // 'computed-type-specifier'.
+ Diag(Loc, diag::err_computed_type_in_declarative_nns)
+ << T->isDecltypeType() << SpecLoc.getTypeLoc().getSourceRange();
}
}
} while ((SpecLoc = SpecLoc.getPrefix()));
diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.id/expr.prim.id.qual/p3.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.id/expr.prim.id.qual/p3.cpp
index c73ffa55a26a31..5da13cc22abef2 100644
--- a/clang/test/CXX/expr/expr.prim/expr.prim.id/expr.prim.id.qual/p3.cpp
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.id/expr.prim.id.qual/p3.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -verify %s
+// RUN: %clang_cc1 -std=c++2c -verify %s
template<typename T>
struct A {
@@ -27,3 +28,18 @@ namespace N {
template<typename T>
void N::E<T>::f() { } // expected-warning {{a declarative nested name specifier cannot name an alias template}}
+
+#if __cplusplus > 202302L
+template<typename... Ts>
+struct A {
+ // FIXME: The nested-name-specifier in the following friend declarations are declarative,
+ // but we don't treat them as such (yet).
+ friend void Ts...[0]::f();
+ template<typename U>
+ friend void Ts...[0]::g();
+
+ friend struct Ts...[0]::B;
+ template<typename U>
+ friend struct Ts...[0]::C; // expected-warning{{is not supported; ignoring this friend declaration}}
+};
+#endif
>From e0646d2098f567ca0cd5642c8694d3d8980134c7 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski <sdkrystian at gmail.com>
Date: Tue, 9 Apr 2024 09:03:25 -0400
Subject: [PATCH 2/5] [FOLD] apply review changes
---
clang/test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp | 4 ++--
clang/test/CXX/drs/dr28xx.cpp | 21 +++++++++++++++++++
.../expr.prim.id/expr.prim.id.qual/p3.cpp | 16 --------------
clang/test/Parser/cxx-class.cpp | 6 +++---
4 files changed, 26 insertions(+), 21 deletions(-)
diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp
index fbe9c0895aeae8..3e67fca9ad7376 100644
--- a/clang/test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp
+++ b/clang/test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp
@@ -6,8 +6,8 @@ class foo {
void func();
};
-int decltype(foo())::i; // expected-error{{'decltype' cannot be used to name a declaration}}
-void decltype(foo())::func() { // expected-error{{'decltype' cannot be used to name a declaration}}
+int decltype(foo())::i; // expected-error{{'decltype' cannot be used in a declarative nested name specifier}}
+void decltype(foo())::func() { // expected-error{{'decltype' cannot be used in a declarative nested name specifier}}
}
diff --git a/clang/test/CXX/drs/dr28xx.cpp b/clang/test/CXX/drs/dr28xx.cpp
index 7f72003d66f1e3..e473bd4158d141 100644
--- a/clang/test/CXX/drs/dr28xx.cpp
+++ b/clang/test/CXX/drs/dr28xx.cpp
@@ -58,3 +58,24 @@ void B<int>::g() requires true;
#endif
} // namespace dr2847
+
+namespace dr2858 { // dr2858: 19
+
+#if __cplusplus > 202302L
+
+template<typename... Ts>
+struct A {
+ // FIXME: The nested-name-specifier in the following friend declarations are declarative,
+ // but we don't treat them as such (yet).
+ friend void Ts...[0]::f();
+ template<typename U>
+ friend void Ts...[0]::g();
+
+ friend struct Ts...[0]::B;
+ template<typename U>
+ friend struct Ts...[0]::C; // expected-warning{{is not supported; ignoring this friend declaration}}
+};
+
+#endif
+
+} // namespace dr2858
diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.id/expr.prim.id.qual/p3.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.id/expr.prim.id.qual/p3.cpp
index 5da13cc22abef2..c73ffa55a26a31 100644
--- a/clang/test/CXX/expr/expr.prim/expr.prim.id/expr.prim.id.qual/p3.cpp
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.id/expr.prim.id.qual/p3.cpp
@@ -1,5 +1,4 @@
// RUN: %clang_cc1 -verify %s
-// RUN: %clang_cc1 -std=c++2c -verify %s
template<typename T>
struct A {
@@ -28,18 +27,3 @@ namespace N {
template<typename T>
void N::E<T>::f() { } // expected-warning {{a declarative nested name specifier cannot name an alias template}}
-
-#if __cplusplus > 202302L
-template<typename... Ts>
-struct A {
- // FIXME: The nested-name-specifier in the following friend declarations are declarative,
- // but we don't treat them as such (yet).
- friend void Ts...[0]::f();
- template<typename U>
- friend void Ts...[0]::g();
-
- friend struct Ts...[0]::B;
- template<typename U>
- friend struct Ts...[0]::C; // expected-warning{{is not supported; ignoring this friend declaration}}
-};
-#endif
diff --git a/clang/test/Parser/cxx-class.cpp b/clang/test/Parser/cxx-class.cpp
index 046d2dd580f02d..342c424705d635 100644
--- a/clang/test/Parser/cxx-class.cpp
+++ b/clang/test/Parser/cxx-class.cpp
@@ -59,14 +59,14 @@ typedef union {
} y;
} bug3177;
-// check that we don't consume the token after the access specifier
+// check that we don't consume the token after the access specifier
// when it's not a colon
class D {
public // expected-error{{expected ':'}}
int i;
};
-// consume the token after the access specifier if it's a semicolon
+// consume the token after the access specifier if it's a semicolon
// that was meant to be a colon
class E {
public; // expected-error{{expected ':'}}
@@ -281,7 +281,7 @@ struct A {} ::PR41192::a; // ok, no missing ';' here expected-warning {{extra q
#if __cplusplus >= 201103L
struct C;
struct D { static C c; };
-struct C {} decltype(D())::c; // expected-error {{'decltype' cannot be used to name a declaration}}
+struct C {} decltype(D())::c; // expected-error {{'decltype' cannot be used in a declarative nested name specifier}}
#endif
}
>From ff6e1ac8f3c44d8b944133341ea5cf04433ceece Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski <sdkrystian at gmail.com>
Date: Tue, 9 Apr 2024 09:10:13 -0400
Subject: [PATCH 3/5] [FOLD] add release note
---
clang/docs/ReleaseNotes.rst | 3 +++
1 file changed, 3 insertions(+)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 30cedbe774be96..29dfddb138c378 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -143,6 +143,9 @@ Resolutions to C++ Defect Reports
compatibility of two types.
(`CWG2759: [[no_unique_address] and common initial sequence <https://cplusplus.github.io/CWG/issues/2759.html>`_).
+- 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>`_).
+
C Language Changes
------------------
>From 3a3058bebdfd3e2c7e9ce54890c895deae440e22 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski <sdkrystian at gmail.com>
Date: Tue, 9 Apr 2024 11:47:08 -0400
Subject: [PATCH 4/5] [FOLD] address review comments
---
clang/test/CXX/drs/dr28xx.cpp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/clang/test/CXX/drs/dr28xx.cpp b/clang/test/CXX/drs/dr28xx.cpp
index e473bd4158d141..9b21d3410a0499 100644
--- a/clang/test/CXX/drs/dr28xx.cpp
+++ b/clang/test/CXX/drs/dr28xx.cpp
@@ -72,8 +72,10 @@ struct A {
friend void Ts...[0]::g();
friend struct Ts...[0]::B;
+ // FIXME: The index of the pack-index-specifier is printed as a memory address in the diagnostic.
template<typename U>
- friend struct Ts...[0]::C; // expected-warning{{is not supported; ignoring this friend declaration}}
+ friend struct Ts...[0]::C;
+ // expected-warning-re at -1 {{dependent nested name specifier 'Ts...[{{.*}}]::' for friend template declaration is not supported; ignoring this friend declaration}}
};
#endif
>From 58fdbf9b1d5bfa9aacb676fcef2baeabf1b5f59f Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski <sdkrystian at gmail.com>
Date: Tue, 9 Apr 2024 11:57:51 -0400
Subject: [PATCH 5/5] [FOLD] reword diagnostic
---
clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 +-
clang/test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp | 4 ++--
clang/test/Parser/cxx-class.cpp | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 2ce2013aac7362..ae8174dc1558d7 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8299,7 +8299,7 @@ def ext_alias_template_in_declarative_nns : ExtWarn<
"a declarative nested name specifier cannot name an alias template">,
InGroup<DiagGroup<"alias-template-in-declaration-name">>;
def err_computed_type_in_declarative_nns : Error<
- "%select{a pack indexing type|'decltype'}0 cannot be used in "
+ "a %select{pack indexing|'decltype'}0 specifier cannot be used in "
"a declarative nested name specifier">;
def err_no_typeid_with_fno_rtti : Error<
diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp
index 3e67fca9ad7376..13be079a40bc35 100644
--- a/clang/test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp
+++ b/clang/test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp
@@ -6,8 +6,8 @@ class foo {
void func();
};
-int decltype(foo())::i; // expected-error{{'decltype' cannot be used in a declarative nested name specifier}}
-void decltype(foo())::func() { // expected-error{{'decltype' cannot be used in a declarative nested name specifier}}
+int decltype(foo())::i; // expected-error{{a 'decltype' specifier cannot be used in a declarative nested name specifier}}
+void decltype(foo())::func() { // expected-error{{a 'decltype' specifier cannot be used in a declarative nested name specifier}}
}
diff --git a/clang/test/Parser/cxx-class.cpp b/clang/test/Parser/cxx-class.cpp
index 342c424705d635..c90c7e030a8bd5 100644
--- a/clang/test/Parser/cxx-class.cpp
+++ b/clang/test/Parser/cxx-class.cpp
@@ -281,7 +281,7 @@ struct A {} ::PR41192::a; // ok, no missing ';' here expected-warning {{extra q
#if __cplusplus >= 201103L
struct C;
struct D { static C c; };
-struct C {} decltype(D())::c; // expected-error {{'decltype' cannot be used in a declarative nested name specifier}}
+struct C {} decltype(D())::c; // expected-error {{a 'decltype' specifier cannot be used in a declarative nested name specifier}}
#endif
}
More information about the cfe-commits
mailing list