llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Vlad Serebrennikov (Endilll)

<details>
<summary>Changes</summary>

This PR adds tests for Core issues against [namespace.def], [namespace.memdef], 
[namespace.unnamed], [namespace.udir], [namespace.qual], and [namespace.alias] 
that didn't have tests (some of them were covered by my previous efforts 
towards P1787R6). I bundled them together, because in general all of them are 
covered by the same subset of the wording.

As a preface, I think it's worth reminding that in addition to regular name 
lookup described in [basic.lookup], there is a "name lookup"-lite for cases 
when name is not looked up in the Standard sense, but declaration matching 
needs to happen, such as terminal names of declarations whose declarator-id is 
a qualified name. This lookup-lite searches for declarations 
[nominable](https://eel.is/c++draft/basic.scope.scope#def:nominable) in a given 
scope that 
[correspond](https://eel.is/c++draft/basic.scope.scope#def:correspond) to a 
given declaration 
([[dcl.meaning]/3.4](https://eel.is/c++draft/dcl.meaning#general-3.4)).

### [CWG165](https://cplusplus.github.io/CWG/issues/165.html) "Definitions of 
friends and block-scope externs"

This was a pre-existing test with a bunch of FIXMEs from 2013 that were no 
longer accurate, so I decided to update them. The difference between the two 
cases there is caused by the fact that the definition of nominable excludes 
declarations that are lexically placed inside a block scope.

### [CWG812](https://cplusplus.github.io/CWG/issues/812.html) "Duplicate names 
in inline namespaces"

Despite the impression that 
[[namespace.def]/6](https://eel.is/c++draft/namespace.def#general-6) might 
leave, inline namespaces introduce a namespace scope like any other namespace 
([[basic.scope.namespace]/1](https://eel.is/c++draft/basic.scope.namespace#<!-- 
-->1)), which means that the declarations they contain have different target 
(i.e. semantic) scope compared to declarations in the enclosing non-inline 
namespace, hence they declare different entities 
([[basic.link]/8](https://eel.is/c++draft/basic.link#<!-- -->8)).

Contrary to what you might expect if you already saw description for CWG986 
below, 
[[namespace.qual]/1](https://eel.is/c++draft/basic.lookup#namespace.qual-1) 
gives inline namespaces special treatment during qualified name lookup: a 
search in a namespace N also contains results from searches in the inline 
namespace set. 
[[basic.lookup.general]/1](https://eel.is/c++draft/basic.lookup#general-1) 
still applies, requiring all the results to denote the same entity, making both 
cases ill-formed.

### [CWG861](https://cplusplus.github.io/CWG/issues/861.html) "Unintended 
ambiguity in inline namespace lookup"
### [CWG861](https://cplusplus.github.io/CWG/issues/861.html) "Unintended 
ambiguity in inline namespace lookup"

---
Full diff: https://github.com/llvm/llvm-project/pull/237113.diff


7 Files Affected:

- (modified) clang/test/CXX/drs/cwg10xx.cpp (+30) 
- (modified) clang/test/CXX/drs/cwg14xx.cpp (+36) 
- (modified) clang/test/CXX/drs/cwg16xx.cpp (+30) 
- (modified) clang/test/CXX/drs/cwg17xx.cpp (+11) 
- (modified) clang/test/CXX/drs/cwg1xx.cpp (+1-2) 
- (modified) clang/test/CXX/drs/cwg8xx.cpp (+40) 
- (modified) clang/test/CXX/drs/cwg9xx.cpp (+64) 


``````````diff
diff --git a/clang/test/CXX/drs/cwg10xx.cpp b/clang/test/CXX/drs/cwg10xx.cpp
index 28c5e2e40129af..cdca0ff35a82d4 100644
--- a/clang/test/CXX/drs/cwg10xx.cpp
+++ b/clang/test/CXX/drs/cwg10xx.cpp
@@ -47,6 +47,10 @@ namespace cwg1004 { // cwg1004: 5
   Third<A<int> > t; // #cwg1004-t
 } // namespace cwg1004
 
+namespace cwg1012 { // cwg1012: 2.7
+static void f() {}
+} // namespace cwg1012
+
 namespace cwg1042 { // cwg1042: 3.5
 #if __cplusplus >= 201402L
   // C++14 added an attribute that we can test the semantics of.
@@ -112,6 +116,32 @@ namespace cwg1070 { // cwg1070: 3.5
 #endif
 } // namespace cwg1070
 
+namespace cwg1077 { // cwg1077: 2.7
+namespace N {
+  template <typename>
+  void f(); // #cwg1077-f
+
+  template <typename, typename>
+  struct S; // #cwg1077-S
+}
+namespace M {
+  template <>
+  void N::f<int>();
+  // expected-error@-1 {{function template specialization of 'f' not in a 
namespace enclosing 'N'}}
+  //   expected-note@#cwg1077-f {{explicitly specialized declaration is here}}
+
+  template <>
+  struct N::S<int, int>;
+  // expected-error@-1 {{class template specialization of 'S' not in a 
namespace enclosing 'N'}}
+  //   expected-note@#cwg1077-S {{explicitly specialized declaration is here}}
+
+  template <typename T>
+  struct N::S<int, T>;
+  // expected-error@-1 {{class template partial specialization of 'S' not in a 
namespace enclosing 'N'}}
+  //   expected-note@#cwg1077-S {{explicitly specialized declaration is here}}
+}
+} // namespace cwg1077
+
 namespace cwg1094 { // cwg1094: 24
 #if __cplusplus >= 201103L
 enum class E : bool { Zero, One };
diff --git a/clang/test/CXX/drs/cwg14xx.cpp b/clang/test/CXX/drs/cwg14xx.cpp
index f3b2bab8e7f3ac..c082cc62c827aa 100644
--- a/clang/test/CXX/drs/cwg14xx.cpp
+++ b/clang/test/CXX/drs/cwg14xx.cpp
@@ -110,6 +110,42 @@ namespace cwg1432 { // cwg1432: 16 open 2022-11-11
 #endif
 } // namespace cwg1432
 
+namespace cwg1439 { // cwg1439: 2.7
+class A {
+  template <typename>
+  friend void f();
+
+  template <typename>
+  friend struct B;
+};
+
+void (*p1)() = &f<int>;
+// expected-error@-1 {{use of undeclared identifier 'f'}}
+
+// FIXME: only the first error is relevant, others are noise
+void (*p2)() = &cwg1439::f<int>;
+// expected-error@-1 {{no member named 'f' in namespace 'cwg1439'}}
+// expected-error@-2 {{expected '(' for function-style cast or type 
construction}}
+// expected-error@-3 {{expected expression}}
+
+B<int>* p3;
+// expected-error@-1 {{no template named 'B'}}
+
+cwg1439::B<int>* p4;
+// expected-error@-1 {{no template named 'B' in namespace 'cwg1439'}}
+
+template <typename>
+void f();
+
+template <typename>
+struct B;
+
+void (*p5)() = &f<int>;
+void (*p6)() = &cwg1439::f<int>;
+B<int>* p7;
+cwg1439::B<int>* p8;
+} // namespace cwg1439
+
 namespace cwg1443 { // cwg1443: 2.7
 struct A {
   int i;
diff --git a/clang/test/CXX/drs/cwg16xx.cpp b/clang/test/CXX/drs/cwg16xx.cpp
index 91cc8261eb6bef..eedb50ca954f9a 100644
--- a/clang/test/CXX/drs/cwg16xx.cpp
+++ b/clang/test/CXX/drs/cwg16xx.cpp
@@ -175,6 +175,36 @@ namespace cwg1653 { // cwg1653: 4 c++17
   }
 } // namespace cwg1653
 
+namespace cwg1657 { // cwg1657: 3.6
+#if __cplusplus >= 201103L
+enum {
+  one [[]]
+  // cxx11-14-error@-1 {{attributes on an enumerator declaration are a C++17 
extension}}
+};
+enum E {
+  two [[]]
+  // cxx11-14-error@-1 {{attributes on an enumerator declaration are a C++17 
extension}}
+};
+enum struct E2 {
+  three [[]]
+  // cxx11-14-error@-1 {{attributes on an enumerator declaration are a C++17 
extension}}
+};
+
+inline namespace [[]] {} // #cwg1657-unnamed
+// cxx11-14-error@-1 {{attributes on a namespace declaration are a C++17 
extension}}
+namespace [[]] {}
+// cxx11-14-error@-1 {{attributes on a namespace declaration are a C++17 
extension}}
+// since-cxx11-warning@-2 {{inline namespace reopened as a non-inline 
namespace}}
+//   since-cxx11-note@#cwg1657-unnamed {{previous definition is here}}
+
+inline namespace [[]] N {}
+// cxx11-14-error@-1 {{attributes on a namespace declaration are a C++17 
extension}}
+
+namespace [[]] M {}
+// cxx11-14-error@-1 {{attributes on a namespace declaration are a C++17 
extension}}
+#endif
+} // namespace cwg1657
+
 namespace cwg1658 { // cwg1658: 5
   namespace DefCtor {
     class A { A(); }; // #cwg1658-A1
diff --git a/clang/test/CXX/drs/cwg17xx.cpp b/clang/test/CXX/drs/cwg17xx.cpp
index 62ea94c4c21733..96280e0ee08a81 100644
--- a/clang/test/CXX/drs/cwg17xx.cpp
+++ b/clang/test/CXX/drs/cwg17xx.cpp
@@ -264,3 +264,14 @@ template auto GLL::operator()<int>(int a) const -> int;
 
 #endif
 } // namespace cwg1780
+
+namespace cwg1795 { // cwg1975: 2.7
+namespace N {
+  struct S{}; // #cwg1795-S
+}
+namespace N {
+  struct S{};
+  // expected-error@-1 {{redefinition of 'S'}}
+  //   expected-note@#cwg1795-S {{previous definition is here}}
+}
+} // namespace cwg1795
diff --git a/clang/test/CXX/drs/cwg1xx.cpp b/clang/test/CXX/drs/cwg1xx.cpp
index e85adff7bb7fba..3bd8cd4c2f5265 100644
--- a/clang/test/CXX/drs/cwg1xx.cpp
+++ b/clang/test/CXX/drs/cwg1xx.cpp
@@ -1005,10 +1005,9 @@ namespace cwg165 { // cwg165: no
     struct A { friend struct B; };
     void f() { void g(); }
   }
-  // FIXME: cwg1477 says this is ok, cwg165 says it's ill-formed
   struct N::B {};
-  // FIXME: cwg165 says this is ill-formed, but the argument in cwg1477 says 
it's ok
   void N::g() {}
+  // FIXME-error@-1 {{'g' is not nominable in 'N'}}
 } // namespace cwg165
 
 namespace cwg166 { // cwg166: 2.9
diff --git a/clang/test/CXX/drs/cwg8xx.cpp b/clang/test/CXX/drs/cwg8xx.cpp
index b512411bdf27b7..688cd0ee27264c 100644
--- a/clang/test/CXX/drs/cwg8xx.cpp
+++ b/clang/test/CXX/drs/cwg8xx.cpp
@@ -6,6 +6,30 @@
 // RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -fexceptions 
-fcxx-exceptions -pedantic-errors -verify-directives 
-verify=expected,since-cxx20,since-cxx11
 // RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -fexceptions 
-fcxx-exceptions -pedantic-errors -verify-directives 
-verify=expected,since-cxx20,since-cxx11
 
+namespace cwg812 { // cwg812: 2.8
+#if __cplusplus >= 201103L
+namespace Q {
+  inline namespace V1 {
+    int i = 1; // #cwg812-v1-i
+    int j = 1; // #cwg812-v1-j
+  }
+  inline namespace V2 {
+    int j = 2; // #cwg812-v2-j
+  }
+  int i = 0;   // #cwg812-Q-i
+}
+
+static_assert(Q::i, "");
+// since-cxx11-error@-1 {{reference to 'i' is ambiguous}}
+//   since-cxx11-note@#cwg812-v1-i {{candidate found by name lookup is 
'cwg812::Q::V1::i'}}
+//   since-cxx11-note@#cwg812-Q-i  {{candidate found by name lookup is 
'cwg812::Q::i'}}
+static_assert(Q::j, "");
+// since-cxx11-error@-1 {{reference to 'j' is ambiguous}}
+//   since-cxx11-note@#cwg812-v1-j {{candidate found by name lookup is 
'cwg812::Q::V1::j'}}
+//   since-cxx11-note@#cwg812-v2-j {{candidate found by name lookup is 
'cwg812::Q::V2::j'}}
+#endif
+} // namespace cwg812
+
 namespace cwg820 { // cwg820: 2.7
 export template <class T> struct B {};
 // cxx98-17-warning@-1 {{exported templates are unsupported}}
@@ -15,6 +39,22 @@ export template<typename T> void f() {}
 // since-cxx20-error@-2 {{export declaration can only be used within a module 
interface}}
 } // namespace cwg820
 
+namespace cwg861 { // cwg861: 2.7
+#if __cplusplus >= 201103L
+namespace A {
+  inline namespace B {
+    namespace C {
+      constexpr int i = 0;
+    }
+    using namespace C;
+  }
+  constexpr int i = 1;
+}
+
+static_assert(A::i == 1, "");
+#endif
+} // namespace cwg861
+
 namespace cwg873 { // cwg873: 3.0
 #if __cplusplus >= 201103L
 template <typename T> void f(T &&);
diff --git a/clang/test/CXX/drs/cwg9xx.cpp b/clang/test/CXX/drs/cwg9xx.cpp
index f218ecddb9686d..2826a69cebcd74 100644
--- a/clang/test/CXX/drs/cwg9xx.cpp
+++ b/clang/test/CXX/drs/cwg9xx.cpp
@@ -15,6 +15,52 @@ namespace std {
   };
 } // namespace std
 
+namespace cwg919 { // cwg919: 2.7
+#if __cplusplus >= 201103L
+namespace N {
+  inline namespace M {
+    template <typename, typename>
+    struct S;
+
+    template <typename>
+    void f();
+  }
+}
+
+template <>
+struct N::S<int, int> {};
+
+template <typename T>
+struct N::S<float, T> {};
+
+template <>
+void N::f<int>() {}
+#endif
+} // namespace cwg919
+
+namespace cwg921 { // cwg921: 3.1
+#if __cplusplus >= 201103L
+namespace N {
+  struct S {};
+  inline namespace M {
+    int f(S);
+  }
+}
+int i = f(N::S{});
+#endif
+} // namespace cwg921
+
+namespace cwg926 { // cwg926: 2.8
+#if __cplusplus >= 201103L
+namespace N {
+  inline namespace {
+    struct S {};
+  }
+}
+N::S s;
+#endif
+} // namespace cwg926
+
 namespace cwg930 { // cwg930: 2.7
 #if __cplusplus >= 201103L
 static_assert(alignof(int[]) == alignof(int), "");
@@ -207,6 +253,24 @@ enum struct E4 : int { e = static_cast<int>(E4()) };
 #endif
 } // namespace cwg977
 
+namespace cwg986 { // cwg986: 2.7
+namespace A {
+  int f(); // #cwg986-A-f
+}
+namespace B {
+  using namespace A;
+  int f();  // #cwg986-B-f
+}
+namespace C {
+  using namespace B;
+  int i = C::f();
+  int j = f();
+  // expected-error@-1 {{call to 'f' is ambiguous}}
+  //   expected-note@#cwg986-A-f {{candidate function}}
+  //   expected-note@#cwg986-B-f {{candidate function}}
+}
+} // namespace cwg986
+
 namespace cwg988 { // cwg988: 2.7
 #if __cplusplus >= 201103L
 void f(int& lvalue_ref, int&& rvalue_ref) {

``````````

</details>


https://github.com/llvm/llvm-project/pull/237113
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to