[clang] 14f245d - [clang] Add test for CWG399

Vlad Serebrennikov via cfe-commits cfe-commits at lists.llvm.org
Sat May 20 01:17:52 PDT 2023


Author: Vlad Serebrennikov
Date: 2023-05-20T11:17:44+03:00
New Revision: 14f245d01a1ee489a13e843e9c77cecf5c7183a9

URL: https://github.com/llvm/llvm-project/commit/14f245d01a1ee489a13e843e9c77cecf5c7183a9
DIFF: https://github.com/llvm/llvm-project/commit/14f245d01a1ee489a13e843e9c77cecf5c7183a9.diff

LOG: [clang] Add test for CWG399

[[https://wg21.link/p1787 | P1787]]: CWG399 is resolved by explicitly appealing to the lookup for the last component of any suitable nested-name-specifier.
Wording: Otherwise, its nested-name-specifier N shall nominate a type. If N has another nested-name-specifier S, Q is looked up as if its lookup context were that nominated by S. ([basic.lookup.qual]/6.2)

CWG399 revisits a resolution to older CWG244. Our test for CWG244 covers many examples from CWG399, and it was updated in 2020 presumably aware of P1787, so I reused CWG244 test. This approach to reusing was discussed in [[https://reviews.llvm.org/D139095 | a CWG405 patch review]].

Reviewed By: #clang-language-wg, aaron.ballman, shafik

Differential Revision: https://reviews.llvm.org/D147920

Added: 
    

Modified: 
    clang/test/CXX/drs/dr2xx.cpp
    clang/test/CXX/drs/dr3xx.cpp
    clang/www/cxx_dr_status.html

Removed: 
    


################################################################################
diff  --git a/clang/test/CXX/drs/dr2xx.cpp b/clang/test/CXX/drs/dr2xx.cpp
index de8ce2b77da4d..c03b7b60bcb4f 100644
--- a/clang/test/CXX/drs/dr2xx.cpp
+++ b/clang/test/CXX/drs/dr2xx.cpp
@@ -500,6 +500,7 @@ namespace dr243 { // dr243: yes
 }
 
 namespace dr244 { // dr244: 11
+                  // NB: this test is reused by dr399
   struct B {}; // expected-note {{type 'dr244::B' found by destructor name lookup}}
   struct D : B {};
 

diff  --git a/clang/test/CXX/drs/dr3xx.cpp b/clang/test/CXX/drs/dr3xx.cpp
index 253fc5d07521e..f1b1941fbddfd 100644
--- a/clang/test/CXX/drs/dr3xx.cpp
+++ b/clang/test/CXX/drs/dr3xx.cpp
@@ -1435,3 +1435,83 @@ namespace dr398 { // dr398: yes
     }
   }
 }
+
+namespace dr399 { // dr399: 11
+                  // NB: reuse dr244 test 
+  struct B {}; // expected-note {{type 'dr244::B' found by destructor name lookup}}
+  struct D : B {};
+
+  D D_object;
+  typedef B B_alias;
+  B* B_ptr = &D_object;
+
+  void f() {
+    D_object.~B(); // expected-error {{does not match the type 'D' of the object being destroyed}}
+    D_object.B::~B();
+    D_object.D::~B(); // FIXME: Missing diagnostic for this.
+    B_ptr->~B();
+    B_ptr->~B_alias();
+    B_ptr->B_alias::~B();
+    B_ptr->B_alias::~B_alias();
+    B_ptr->dr244::~B(); // expected-error {{refers to a member in namespace}}
+    B_ptr->dr244::~B_alias(); // expected-error {{refers to a member in namespace}}
+  }
+
+  template<typename T, typename U>
+  void f(T *B_ptr, U D_object) {
+    D_object.~B(); // FIXME: Missing diagnostic for this.
+    D_object.B::~B();
+    D_object.D::~B(); // FIXME: Missing diagnostic for this.
+    B_ptr->~B();
+    B_ptr->~B_alias();
+    B_ptr->B_alias::~B();
+    B_ptr->B_alias::~B_alias();
+    B_ptr->dr399::~B(); // expected-error {{does not refer to a type name}}
+    B_ptr->dr399::~B_alias(); // expected-error {{does not refer to a type name}}
+  }
+  template void f<B, D>(B*, D);
+
+  namespace N {
+    template<typename T> struct E {};
+    typedef E<int> F;
+  }
+  void g(N::F f) {
+    typedef N::F G; // expected-note {{found by destructor name lookup}}
+    f.~G();
+    f.G::~E(); // expected-error {{ISO C++ requires the name after '::~' to be found in the same scope as the name before '::~'}}
+    f.G::~F(); // expected-error {{undeclared identifier 'F' in destructor name}}
+    f.G::~G();
+    // This is technically ill-formed; E is looked up in 'N::' and names the
+    // class template, not the injected-class-name of the class. But that's
+    // probably a bug in the standard.
+    f.N::F::~E(); // expected-error {{ISO C++ requires the name after '::~' to be found in the same scope as the name before '::~'}}
+    // This is valid; we look up the second F in the same scope in which we
+    // found the first one, that is, 'N::'.
+    f.N::F::~F();
+    // This is technically ill-formed; G is looked up in 'N::' and is not found.
+    // Rejecting this seems correct, but most compilers accept, so we do also.
+    f.N::F::~G(); // expected-error {{qualified destructor name only found in lexical scope; omit the qualifier to find this type name by unqualified lookup}}
+  }
+
+  // Bizarrely, compilers perform lookup in the scope for qualified destructor
+  // names, if the nested-name-specifier is non-dependent. Ensure we diagnose
+  // this.
+  namespace QualifiedLookupInScope {
+    namespace N {
+      template <typename> struct S { struct Inner {}; };
+    }
+    template <typename U> void f(typename N::S<U>::Inner *p) {
+      typedef typename N::S<U>::Inner T;
+      p->::dr399::QualifiedLookupInScope::N::S<U>::Inner::~T(); // expected-error {{no type named 'T' in}}
+    }
+    template void f<int>(N::S<int>::Inner *); // expected-note {{instantiation of}}
+
+    template <typename U> void g(U *p) {
+      typedef U T;
+      p->T::~T();
+      p->U::~T();
+      p->::dr399::QualifiedLookupInScope::N::S<int>::Inner::~T(); // expected-error {{'T' does not refer to a type name}}
+    }
+    template void g(N::S<int>::Inner *);
+  }
+}

diff  --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html
index 6206ea6664873..6a04e17ecc137 100755
--- a/clang/www/cxx_dr_status.html
+++ b/clang/www/cxx_dr_status.html
@@ -2433,7 +2433,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
     <td><a href="https://cplusplus.github.io/CWG/issues/399.html">399</a></td>
     <td>CD6</td>
     <td>Destructor lookup redux</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Clang 11</td>
   </tr>
   <tr id="400">
     <td><a href="https://cplusplus.github.io/CWG/issues/400.html">400</a></td>


        


More information about the cfe-commits mailing list