[clang] 198ffb8 - [Clang][Sema] Implement approved resolution for CWG2858 (#88042)

via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 11 08:23:27 PDT 2024


Author: Krystian Stasiowski
Date: 2024-04-11T11:23:24-04:00
New Revision: 198ffb85314f7741ed048de67d68ca83bb30e16e

URL: https://github.com/llvm/llvm-project/commit/198ffb85314f7741ed048de67d68ca83bb30e16e
DIFF: https://github.com/llvm/llvm-project/commit/198ffb85314f7741ed048de67d68ca83bb30e16e.diff

LOG: [Clang][Sema] Implement approved resolution for CWG2858 (#88042)

The approved resolution for CWG2858 changes
[expr.prim.id.qual] p2 sentence 2 to read:
> A declarative _nested-name-specifier_ shall not have a
_computed-type-specifier_.

This patch implements the approved resolution. Since we don't consider
_nested-name-specifiers_ in friend declarations to be declarative (yet),
it currently isn't possible to write a test that would produce this
diagnostic (`diagnoseQualifiedDeclaration` is never called if the
`DeclContext` can't be computed). Nevertheless, tests were added which
will produce the diagnostic once we start calling
`diagnoseQualifiedDeclaration` for friend declarations.

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/lib/Sema/SemaDecl.cpp
    clang/test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp
    clang/test/CXX/drs/dr28xx.cpp
    clang/test/Parser/cxx-class.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c4a4893aec5cd6..93318871fa9f6e 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -147,6 +147,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
 ------------------
 

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 059a8f58da5db1..180e913155d67c 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">,
@@ -8313,6 +8309,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<
+  "a %select{pack indexing|'decltype'}0 specifier 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 5a23179dfbbf44..a4699d6ba2c735 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/dcl.decl/dcl.meaning/p1-0x.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp
index fbe9c0895aeae8..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 to name a declaration}}
-void decltype(foo())::func() { // expected-error{{'decltype' cannot be used to name a declaration}}
+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/CXX/drs/dr28xx.cpp b/clang/test/CXX/drs/dr28xx.cpp
index 7f72003d66f1e3..9b21d3410a0499 100644
--- a/clang/test/CXX/drs/dr28xx.cpp
+++ b/clang/test/CXX/drs/dr28xx.cpp
@@ -58,3 +58,26 @@ 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;
+  // 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-re at -1 {{dependent nested name specifier 'Ts...[{{.*}}]::' for friend template declaration is not supported; ignoring this friend declaration}}
+};
+
+#endif
+
+} // namespace dr2858

diff  --git a/clang/test/Parser/cxx-class.cpp b/clang/test/Parser/cxx-class.cpp
index 046d2dd580f02d..c90c7e030a8bd5 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 {{a 'decltype' specifier cannot be used in a declarative nested name specifier}}
 #endif
 }
 


        


More information about the cfe-commits mailing list