[clang] [clang][NFC] Add test for CWG issues about linkage in cross-TU context (PR #113736)

Vlad Serebrennikov via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 28 05:04:45 PDT 2024


https://github.com/Endilll updated https://github.com/llvm/llvm-project/pull/113736

>From b23ce76d3db79eab6433bef1bd3fc9d26bcb3309 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Fri, 25 Oct 2024 23:05:06 +0300
Subject: [PATCH 1/5] [clang][NFC] Add test for CWG issues about linkage in
 cross-TU context

---
 clang/test/CXX/drs/cwg1884.cpp | 548 +++++++++++++++++++++++++++++++++
 clang/test/CXX/drs/cwg18xx.cpp |   2 +
 clang/test/CXX/drs/cwg279.cpp  |  42 +++
 clang/test/CXX/drs/cwg2xx.cpp  |   2 +
 clang/test/CXX/drs/cwg3xx.cpp  |   2 +
 clang/www/cxx_dr_status.html   |   6 +-
 6 files changed, 599 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/CXX/drs/cwg1884.cpp
 create mode 100644 clang/test/CXX/drs/cwg279.cpp

diff --git a/clang/test/CXX/drs/cwg1884.cpp b/clang/test/CXX/drs/cwg1884.cpp
new file mode 100644
index 00000000000000..d8fa9c4373765c
--- /dev/null
+++ b/clang/test/CXX/drs/cwg1884.cpp
@@ -0,0 +1,548 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: split-file --leading-lines %s %t
+// RUN: %clang_cc1 -std=c++20 -pedantic-errors -fexceptions -fcxx-exceptions %t/cwg1884_A.cppm -triple x86_64-unknown-unknown -emit-module-interface -o %t/cwg1884_A.pcm
+// RUN: %clang_cc1 -std=c++20 -verify=since-cxx20 -pedantic-errors -fexceptions -fcxx-exceptions -triple x86_64-unknown-unknown %t/cwg1884.cpp -fmodule-file=cwg1884_A=%t/cwg1884_A.pcm
+// RUN: %clang_cc1 -std=c++23 -pedantic-errors -fexceptions -fcxx-exceptions %t/cwg1884_A.cppm -triple x86_64-unknown-unknown -emit-module-interface -o %t/cwg1884_A.pcm
+// RUN: %clang_cc1 -std=c++23 -verify=since-cxx20 -pedantic-errors -fexceptions -fcxx-exceptions -triple x86_64-unknown-unknown %t/cwg1884.cpp -fmodule-file=cwg1884_A=%t/cwg1884_A.pcm
+// RUN: %clang_cc1 -std=c++2c -pedantic-errors -fexceptions -fcxx-exceptions %t/cwg1884_A.cppm -triple x86_64-unknown-unknown -emit-module-interface -o %t/cwg1884_A.pcm
+// RUN: %clang_cc1 -std=c++2c -verify=since-cxx20 -pedantic-errors -fexceptions -fcxx-exceptions -triple x86_64-unknown-unknown %t/cwg1884.cpp -fmodule-file=cwg1884_A=%t/cwg1884_A.pcm
+
+// cwg1884: partial
+
+// _N4993_.[basic.link]/11:
+// For any two declarations of an entity E:
+//   — If one declares E to be a variable or function,
+//     the other shall declare E as one of the same type.
+//   — If one declares E to be an enumerator, the other shall do so.
+//   — If one declares E to be a namespace, the other shall do so.
+//   — If one declares E to be a type,
+//     the other shall declare E to be a type of the same kind (9.2.9.5).
+//   — If one declares E to be a class template,
+//     the other shall do so with the same kind and an equivalent template-head (13.7.7.2).
+//     [Note 5 : The declarations can supply different default template arguments. — end note]
+//   — If one declares E to be a function template or a (partial specialization of a) variable template,
+//     the other shall declare E to be one with an equivalent template-head and type.
+//   — If one declares E to be an alias template,
+//     the other shall declare E to be one with an equivalent template-head and defining-type-id.
+//   — If one declares E to be a concept, the other shall do so.
+// Types are compared after all adjustments of types (during which typedefs (9.2.4) are replaced by their definitions);
+// declarations for an array object can specify array types that differ by the presence or absence of a major array bound (9.3.4.5).
+// No diagnostic is required if neither declaration is reachable from the other.
+
+// The structure of the test is the following. First, module cwg1884_A
+// provides all (significant) kinds of entities, each named 'a' through 'k'.
+// Then the .cpp file does MxN kind of testing, where it tests one kind of entity
+// against every other kind.
+
+//--- cwg1884_A.cppm
+export module cwg1884_A;
+
+export {
+int a;
+void b();
+enum E { c };
+namespace d {}
+struct e;
+class f;
+template <typename>
+class g;
+template <typename>
+void h(int);
+template <typename, typename>
+int i;
+template <typename>
+using j = int;
+template <typename>
+concept k = true;
+} // export
+
+
+//--- cwg1884.cpp
+import cwg1884_A;
+
+// int a;
+
+void a();
+// since-cxx20-error at -1 {{redefinition of 'a' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:42 {{previous definition is here}}
+enum Ea {
+  a
+  // since-cxx20-error at -1 {{redefinition of 'a'}}
+  //   since-cxx20-note at cwg1884_A.cppm:42 {{previous definition is here}}
+};
+namespace a {} // #cwg1884-namespace-a
+// since-cxx20-error at -1 {{redefinition of 'a' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:42 {{previous definition is here}}
+struct a;
+// since-cxx20-error at -1 {{redefinition of 'a' as different kind of symbol}}
+//   since-cxx20-note@#cwg1884-namespace-a {{previous definition is here}}
+class a;
+// since-cxx20-error at -1 {{redefinition of 'a' as different kind of symbol}}
+//   since-cxx20-note@#cwg1884-namespace-a {{previous definition is here}}
+template <typename>
+class a;
+// since-cxx20-error at -1 {{redefinition of 'a' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:42 {{previous definition is here}}
+template <typename>
+void a(int);
+// since-cxx20-error at -1 {{redefinition of 'a' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:42 {{previous definition is here}}
+template <typename, typename>
+int a;
+// since-cxx20-error at -1 {{redefinition of 'a' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:42 {{previous definition is here}}
+template <typename T>
+int a<T, int>;
+// since-cxx20-error at -1 {{redefinition of 'a' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:42 {{previous definition is here}}
+// since-cxx20-error at -3 {{expected ';' after top level declarator}}
+template <typename>
+using a = int;
+// since-cxx20-error at -1 {{redefinition of 'a' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:42 {{previous definition is here}}
+template <typename>
+concept a = true;
+// since-cxx20-error at -1 {{redefinition of 'a' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:42 {{previous definition is here}}
+
+
+// void b();
+
+int b;
+// since-cxx20-error at -1 {{redefinition of 'b' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:43 {{previous definition is here}}
+enum Eb {
+  b
+  // since-cxx20-error at -1 {{redefinition of 'b'}}
+  //   since-cxx20-note at cwg1884_A.cppm:43 {{previous definition is here}}
+};
+namespace b {} // #cwg1884-namespace-b
+// since-cxx20-error at -1 {{redefinition of 'b' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:43 {{previous definition is here}}
+struct b;
+// since-cxx20-error at -1 {{redefinition of 'b' as different kind of symbol}}
+//   since-cxx20-note@#cwg1884-namespace-b {{previous definition is here}}
+class b;
+// since-cxx20-error at -1 {{redefinition of 'b' as different kind of symbol}}
+//   since-cxx20-note@#cwg1884-namespace-b {{previous definition is here}}
+template <typename>
+class b;
+// since-cxx20-error at -1 {{redefinition of 'b' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:43 {{previous definition is here}}
+template <typename>
+void b(int); // #cwg1884-func-template-b
+// @-1 OK, a non-corresponding overload
+template <typename, typename>
+int b;
+// since-cxx20-error at -1 {{redefinition of 'b' as different kind of symbol}}
+//   since-cxx20-note@#cwg1884-func-template-b {{previous definition is here}}
+template <typename T>
+int b<T, int>;
+// since-cxx20-error at -1 {{no variable template matches specialization; did you mean to use 'b' as function template instead?}}
+template <typename>
+using b = int;
+// since-cxx20-error at -1 {{redefinition of 'b' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:43 {{previous definition is here}}
+template <typename>
+concept b = true;
+// since-cxx20-error at -1 {{redefinition of 'b' as different kind of symbol}}
+//   since-cxx20-note@#cwg1884-func-template-b {{previous definition is here}}
+
+
+// enum E { c };
+
+int c;
+// since-cxx20-error at -1 {{redefinition of 'c' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:44 {{previous definition is here}}
+void c();
+// since-cxx20-error at -1 {{redefinition of 'c' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:44 {{previous definition is here}}
+namespace c {} // #cwg1884-namespace-c
+// since-cxx20-error at -1 {{redefinition of 'c' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:44 {{previous definition is here}}
+struct c;
+// since-cxx20-error at -1 {{redefinition of 'c' as different kind of symbol}}
+//   since-cxx20-note@#cwg1884-namespace-c {{previous definition is here}}
+class c;
+// since-cxx20-error at -1 {{redefinition of 'c' as different kind of symbol}}
+//   since-cxx20-note@#cwg1884-namespace-c {{previous definition is here}}
+template <typename>
+class c;
+// since-cxx20-error at -1 {{redefinition of 'c' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:44 {{previous definition is here}}
+template <typename>
+void c(int);
+// since-cxx20-error at -1 {{redefinition of 'c' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:44 {{previous definition is here}}
+template <typename, typename>
+int c;
+// since-cxx20-error at -1 {{redefinition of 'c' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:44 {{previous definition is here}}
+template <typename T>
+int c<T, int>;
+// since-cxx20-error at -1 {{redefinition of 'c' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:44 {{previous definition is here}}
+// since-cxx20-error at -3 {{expected ';' after top level declarator}}
+template <typename>
+using c = int;
+// since-cxx20-error at -1 {{redefinition of 'c' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:44 {{previous definition is here}}
+template <typename>
+concept c = true;
+// since-cxx20-error at -1 {{redefinition of 'c' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:44 {{previous definition is here}}
+
+
+// namespace d {};
+
+int d;
+// since-cxx20-error at -1 {{redefinition of 'd' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:45 {{previous definition is here}}
+void d();
+// since-cxx20-error at -1 {{redefinition of 'd' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:45 {{previous definition is here}}
+enum Ed {
+  d
+  // since-cxx20-error at -1 {{redefinition of 'd'}}
+  //   since-cxx20-note at cwg1884_A.cppm:45 {{previous definition is here}}
+};
+struct d;
+// since-cxx20-error at -1 {{redefinition of 'd' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:45 {{previous definition is here}}
+class d;
+// since-cxx20-error at -1 {{redefinition of 'd' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:45 {{previous definition is here}}
+template <typename>
+class d;
+// since-cxx20-error at -1 {{redefinition of 'd' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:45 {{previous definition is here}}
+template <typename>
+void d(int);
+// since-cxx20-error at -1 {{redefinition of 'd' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:45 {{previous definition is here}}
+template <typename, typename>
+int d;
+// since-cxx20-error at -1 {{redefinition of 'd' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:45 {{previous definition is here}}
+template <typename T>
+int d<T, int>;
+// since-cxx20-error at -1 {{redefinition of 'd' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:45 {{previous definition is here}}
+// since-cxx20-error at -3 {{expected ';' after top level declarator}}
+template <typename>
+using d = int;
+// since-cxx20-error at -1 {{redefinition of 'd' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:45 {{previous definition is here}}
+template <typename>
+concept d = true;
+// since-cxx20-error at -1 {{redefinition of 'd' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:45 {{previous definition is here}}
+
+
+// struct e;
+
+int e; // #cwg1884-int-e
+// @-1 OK, types and variables do not correspond
+void e();
+// since-cxx20-error at -1 {{redefinition of 'e' as different kind of symbol}}
+//   since-cxx20-note@#cwg1884-int-e {{previous definition is here}}
+enum Ee {
+  e
+  // since-cxx20-error at -1 {{redefinition of 'e'}}
+  //   since-cxx20-note@#cwg1884-int-e {{previous definition is here}}
+};
+namespace e {} // #cwg1884-namespace-e
+// since-cxx20-error at -1 {{redefinition of 'e' as different kind of symbol}}
+//   since-cxx20-note@#cwg1884-int-e {{previous definition is here}}
+class e;
+// since-cxx20-error at -1 {{declaration of 'e' in the global module follows declaration in module cwg1884_A}}
+//   since-cxx20-note at cwg1884_A.cppm:46 {{previous declaration is here}}
+template <typename>
+class e;
+// since-cxx20-error at -1 {{redefinition of 'e' as different kind of symbol}}
+//   since-cxx20-note@#cwg1884-int-e {{previous definition is here}}
+template <typename>
+void e(int);
+// since-cxx20-error at -1 {{redefinition of 'e' as different kind of symbol}}
+//   since-cxx20-note@#cwg1884-int-e {{previous definition is here}}
+template <typename, typename>
+int e;
+// since-cxx20-error at -1 {{redefinition of 'e' as different kind of symbol}}
+//   since-cxx20-note@#cwg1884-int-e {{previous definition is here}}
+template <typename T>
+int e<T, int>;
+// since-cxx20-error at -1 {{redefinition of 'e' as different kind of symbol}}
+//   since-cxx20-note@#cwg1884-int-e {{previous definition is here}}
+// since-cxx20-error at -3 {{expected ';' after top level declarator}}
+template <typename>
+using e = int;
+// since-cxx20-error at -1 {{redefinition of 'e' as different kind of symbol}}
+//   since-cxx20-note@#cwg1884-int-e {{previous definition is here}}
+template <typename>
+concept e = true;
+// since-cxx20-error at -1 {{redefinition of 'e' as different kind of symbol}}
+//   since-cxx20-note@#cwg1884-int-e {{previous definition is here}}
+
+
+// class f;
+
+int f; // #cwg1884-int-f
+// @-1 OK, types and variables do not correspond
+void f();
+// since-cxx20-error at -1 {{redefinition of 'f' as different kind of symbol}}
+//   since-cxx20-note@#cwg1884-int-f {{previous definition is here}}
+enum Ef {
+  f
+  // since-cxx20-error at -1 {{redefinition of 'f'}}
+  //   since-cxx20-note@#cwg1884-int-f {{previous definition is here}}
+};
+namespace f {} // #cwg1884-namespace-f
+// since-cxx20-error at -1 {{redefinition of 'f' as different kind of symbol}}
+//   since-cxx20-note@#cwg1884-int-f {{previous definition is here}}
+struct f;
+// since-cxx20-error at -1 {{declaration of 'f' in the global module follows declaration in module cwg1884_A}}
+//   since-cxx20-note at cwg1884_A.cppm:47 {{previous declaration is here}}
+template <typename>
+class f;
+// since-cxx20-error at -1 {{redefinition of 'f' as different kind of symbol}}
+//   since-cxx20-note@#cwg1884-int-f {{previous definition is here}}
+template <typename>
+void f(int);
+// since-cxx20-error at -1 {{redefinition of 'f' as different kind of symbol}}
+//   since-cxx20-note@#cwg1884-int-f {{previous definition is here}}
+template <typename, typename>
+int f;
+// since-cxx20-error at -1 {{redefinition of 'f' as different kind of symbol}}
+//   since-cxx20-note@#cwg1884-int-f {{previous definition is here}}
+template <typename T>
+int f<T, int>;
+// since-cxx20-error at -1 {{redefinition of 'f' as different kind of symbol}}
+//   since-cxx20-note@#cwg1884-int-f {{previous definition is here}}
+// since-cxx20-error at -3 {{expected ';' after top level declarator}}
+template <typename>
+using f = int;
+// since-cxx20-error at -1 {{redefinition of 'f' as different kind of symbol}}
+//   since-cxx20-note@#cwg1884-int-f {{previous definition is here}}
+template <typename>
+concept f = true;
+// since-cxx20-error at -1 {{redefinition of 'f' as different kind of symbol}}
+//   since-cxx20-note@#cwg1884-int-f {{previous definition is here}}
+
+
+// template <typename>
+// class g;
+
+int g;
+// since-cxx20-error at -1 {{redefinition of 'g' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:49 {{previous definition is here}}
+void g();
+// since-cxx20-error at -1 {{redefinition of 'g' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:49 {{previous definition is here}}
+enum Eg {
+  g
+  // since-cxx20-error at -1 {{redefinition of 'g'}}
+  //   since-cxx20-note at cwg1884_A.cppm:49 {{previous definition is here}}
+};
+namespace g {}
+// since-cxx20-error at -1 {{redefinition of 'g' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:49 {{previous definition is here}}
+struct g;
+// since-cxx20-error at -1 {{redefinition of 'g' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:49 {{previous definition is here}}
+class g;
+// since-cxx20-error at -1 {{redefinition of 'g' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:49 {{previous definition is here}}
+template <typename>
+void g(int);
+// since-cxx20-error at -1 {{redefinition of 'g' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:49 {{previous definition is here}}
+template <typename, typename>
+int g;
+// since-cxx20-error at -1 {{redefinition of 'g' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:49 {{previous definition is here}}
+template <typename T>
+int g<T, int>;
+// since-cxx20-error at -1 {{no variable template matches partial specialization}}
+template <typename>
+using g = int;
+// since-cxx20-error at -1 {{redefinition of 'g' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:49 {{previous definition is here}}
+template <typename>
+concept g = true;
+// since-cxx20-error at -1 {{redefinition of 'g' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:49 {{previous definition is here}}
+
+
+// template <typename>
+// void h(int);
+
+int h;
+// since-cxx20-error at -1 {{redefinition of 'h' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:51 {{previous definition is here}}
+void h(); // #cwg1884-function-f
+// @-1 OK, a non-corresponding overload
+enum Eh {
+  h
+  // FIXME-since-cxx20-error at -1 {{redefinition of 'h'}}
+  //   FIXME-since-cxx20-note at cwg1884_A.cppm:51 {{previous definition is here}}
+};
+namespace h {} // #cwg1884-namespace-h
+// FIXME-since-cxx20-error at -1 {{redefinition of 'h' as different kind of symbol}}
+//   FIXME-since-cxx20-note at cwg1884_A.cppm:51 {{previous definition is here}}
+struct h;
+// since-cxx20-error at -1 {{redefinition of 'h' as different kind of symbol}}
+//   since-cxx20-note@#cwg1884-namespace-h {{previous definition is here}}
+class h;
+// since-cxx20-error at -1 {{redefinition of 'h' as different kind of symbol}}
+//   since-cxx20-note@#cwg1884-namespace-h {{previous definition is here}}
+template <typename>
+class h;
+// FIXME-since-cxx20-error at -1 {{redefinition of 'h' as different kind of symbol}}
+//   FIXME-since-cxx20-note at cwg1884_A.cppm:51 {{previous definition is here}}
+template <typename, typename>
+int h;
+// since-cxx20-error at -1 {{redefinition of 'h' as different kind of symbol}}
+//   since-cxx20-note@#cwg1884-namespace-h {{previous definition is here}}
+template <typename T>
+int h<T, int>;
+// since-cxx20-error at -1 {{no variable template matches specialization; did you mean to use 'h' as function template instead?}}
+template <typename>
+using h = int;
+// since-cxx20-error at -1 {{redefinition of 'h' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:51 {{previous definition is here}}
+template <typename>
+concept h = true;
+// since-cxx20-error at -1 {{redefinition of 'h' as different kind of symbol}}
+//   since-cxx20-note@#cwg1884-function-f {{previous definition is here}}
+
+
+// template <typename, typename>
+// int i;
+
+int i;
+// since-cxx20-error at -1 {{redefinition of 'i' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:53 {{previous definition is here}}
+void i();
+// since-cxx20-error at -1 {{redefinition of 'i' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:53 {{previous definition is here}}
+enum Ei {
+  i
+  // since-cxx20-error at -1 {{redefinition of 'i'}}
+  //   since-cxx20-note at cwg1884_A.cppm:53 {{previous definition is here}}
+};
+namespace i {}
+// since-cxx20-error at -1 {{redefinition of 'i' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:53 {{previous definition is here}}
+struct i;
+// since-cxx20-error at -1 {{redefinition of 'i' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:53 {{previous definition is here}}
+class i;
+// since-cxx20-error at -1 {{redefinition of 'i' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:53 {{previous definition is here}}
+template <typename>
+class i;
+// since-cxx20-error at -1 {{redefinition of 'i' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:53 {{previous definition is here}}
+template <typename>
+void i(int);
+// since-cxx20-error at -1 {{redefinition of 'i' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:53 {{previous definition is here}}
+template <typename T>
+int i<T, int>; // OK, partial specialization
+template <typename>
+using i = int;
+// since-cxx20-error at -1 {{redefinition of 'i' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:53 {{previous definition is here}}
+template <typename>
+concept i = true;
+// since-cxx20-error at -1 {{redefinition of 'i' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:53 {{previous definition is here}}
+
+
+// template <typename>
+// using j = int;
+
+int j;
+// since-cxx20-error at -1 {{redefinition of 'j' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:55 {{previous definition is here}}
+void j();
+// since-cxx20-error at -1 {{redefinition of 'j' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:55 {{previous definition is here}}
+enum Ej {
+  j
+  // since-cxx20-error at -1 {{redefinition of 'j'}}
+  //   since-cxx20-note at cwg1884_A.cppm:55 {{previous definition is here}}
+};
+namespace j {}
+// since-cxx20-error at -1 {{redefinition of 'j' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:55 {{previous definition is here}}
+struct j;
+// since-cxx20-error at -1 {{redefinition of 'j' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:55 {{previous definition is here}}
+class j;
+// since-cxx20-error at -1 {{redefinition of 'j' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:55 {{previous definition is here}}
+template <typename>
+class j;
+// since-cxx20-error at -1 {{redefinition of 'j' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:55 {{previous definition is here}}
+template <typename>
+void j(int);
+// since-cxx20-error at -1 {{redefinition of 'j' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:55 {{previous definition is here}}
+template <typename, typename>
+int j;
+// since-cxx20-error at -1 {{redefinition of 'j' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:55 {{previous definition is here}}
+template <typename T>
+int j<T, int>;
+// since-cxx20-error at -1 {{no variable template matches partial specialization}}
+template <typename>
+concept j = true;
+// since-cxx20-error at -1 {{redefinition of 'j' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:55 {{previous definition is here}}
+
+
+// template <typename>
+// concept k = true;
+
+int k;
+// since-cxx20-error at -1 {{redefinition of 'k' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:57 {{previous definition is here}}
+void k();
+// since-cxx20-error at -1 {{redefinition of 'k' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:57 {{previous definition is here}}
+enum Ek {
+  k
+  // since-cxx20-error at -1 {{redefinition of 'k'}}
+  //   since-cxx20-note at cwg1884_A.cppm:57 {{previous definition is here}}
+};
+namespace k {}
+// since-cxx20-error at -1 {{redefinition of 'k' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:57 {{previous definition is here}}
+struct k;
+// since-cxx20-error at -1 {{redefinition of 'k' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:57 {{previous definition is here}}
+class k;
+// since-cxx20-error at -1 {{redefinition of 'k' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:57 {{previous definition is here}}
+template <typename>
+class k;
+// since-cxx20-error at -1 {{redefinition of 'k' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:57 {{previous definition is here}}
+template <typename>
+void k(int);
+// since-cxx20-error at -1 {{redefinition of 'k' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:57 {{previous definition is here}}
+template <typename, typename>
+int k;
+// since-cxx20-error at -1 {{redefinition of 'k' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:57 {{previous definition is here}}
+template <typename T>
+int k<T, int>;
+// since-cxx20-error at -1 {{no variable template matches partial specialization}}
+template <typename>
+using k = int;
+// since-cxx20-error at -1 {{redefinition of 'k' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:57 {{previous definition is here}}
diff --git a/clang/test/CXX/drs/cwg18xx.cpp b/clang/test/CXX/drs/cwg18xx.cpp
index b059492637bd5c..0fd2cd6b2d870c 100644
--- a/clang/test/CXX/drs/cwg18xx.cpp
+++ b/clang/test/CXX/drs/cwg18xx.cpp
@@ -547,6 +547,8 @@ namespace cwg1881 { // cwg1881: 7
   static_assert(!__is_standard_layout(D), "");
 }
 
+// cwg1884 is in cwg1884.cpp
+
 namespace cwg1890 { // cwg1890: no drafting 2018-06-04
 // FIXME: current consensus for CWG2335 is that the examples are well-formed.
 namespace ex1 {
diff --git a/clang/test/CXX/drs/cwg279.cpp b/clang/test/CXX/drs/cwg279.cpp
new file mode 100644
index 00000000000000..3f3782b79ebff8
--- /dev/null
+++ b/clang/test/CXX/drs/cwg279.cpp
@@ -0,0 +1,42 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: split-file --leading-lines %s %t
+// RUN: %clang_cc1 -std=c++20 -pedantic-errors -fexceptions -fcxx-exceptions %t/cwg279_A.cppm -triple x86_64-unknown-unknown -emit-module-interface -o %t/cwg279_A.pcm
+// RUN: %clang_cc1 -std=c++20 -verify=since-cxx20 -pedantic-errors -fexceptions -fcxx-exceptions -triple x86_64-unknown-unknown %t/cwg279.cpp -fmodule-file=cwg279_A=%t/cwg279_A.pcm
+// RUN: %clang_cc1 -std=c++23 -pedantic-errors -fexceptions -fcxx-exceptions %t/cwg279_A.cppm -triple x86_64-unknown-unknown -emit-module-interface -o %t/cwg279_A.pcm
+// RUN: %clang_cc1 -std=c++23 -verify=since-cxx20 -pedantic-errors -fexceptions -fcxx-exceptions -triple x86_64-unknown-unknown %t/cwg279.cpp -fmodule-file=cwg279_A=%t/cwg279_A.pcm
+// RUN: %clang_cc1 -std=c++2c -pedantic-errors -fexceptions -fcxx-exceptions %t/cwg279_A.cppm -triple x86_64-unknown-unknown -emit-module-interface -o %t/cwg279_A.pcm
+// RUN: %clang_cc1 -std=c++2c -verify=since-cxx20 -pedantic-errors -fexceptions -fcxx-exceptions -triple x86_64-unknown-unknown %t/cwg279.cpp -fmodule-file=cwg279_A=%t/cwg279_A.pcm
+
+// cwg279: no
+
+//--- cwg279_A.cppm
+export module cwg279_A;
+
+export {
+struct S; // #cwg279-S
+extern S *q; // #cwg279-q
+
+struct S2 {}; // #cwg279-S2
+extern S2 *q2; // #cwg279-q2
+} // export
+
+//--- cwg279.cpp
+import cwg279_A;
+
+// FIXME: We should use markers instead. They are less fragile,
+//        but -verify doesn't support them across modules yet.
+// FIXME: This is well-formed. Previous "definition" is actually just a declaration.
+typedef struct {} S;
+// since-cxx20-error at -1 {{typedef redefinition with different types ('struct S' vs 'S')}}
+//   since-cxx20-note at cwg279_A.cppm:17 {{previous definition is here}}
+extern S *q;
+// since-cxx20-error at -1 {{declaration of 'q' in the global module follows declaration in module cwg279_A}}
+//   since-cxx20-note at cwg279_A.cppm:18 {{previous declaration is here}}
+
+typedef struct {} S2;
+// since-cxx20-error at -1 {{typedef redefinition with different types ('struct S2' vs 'S2')}}
+//   since-cxx20-note at cwg279_A.cppm:20 {{previous definition is here}}
+extern S2 *q2;
+// since-cxx20-error at -1 {{declaration of 'q2' in the global module follows declaration in module cwg279_A}}
+//   since-cxx20-note at cwg279_A.cppm:21 {{previous declaration is here}}
diff --git a/clang/test/CXX/drs/cwg2xx.cpp b/clang/test/CXX/drs/cwg2xx.cpp
index 926cb19596026b..ec37b420880e28 100644
--- a/clang/test/CXX/drs/cwg2xx.cpp
+++ b/clang/test/CXX/drs/cwg2xx.cpp
@@ -1032,6 +1032,8 @@ namespace cwg277 { // cwg277: 3.1
   static_assert(__enable_constant_folding(!intp()), "");
 }
 
+// cwg279 is in cwg279.cpp
+
 namespace cwg280 { // cwg280: 2.9
   typedef void f0();
   typedef void f1(int);
diff --git a/clang/test/CXX/drs/cwg3xx.cpp b/clang/test/CXX/drs/cwg3xx.cpp
index f20054c3701b1c..10c8d86ed16a0d 100644
--- a/clang/test/CXX/drs/cwg3xx.cpp
+++ b/clang/test/CXX/drs/cwg3xx.cpp
@@ -637,6 +637,8 @@ namespace cwg337 { // cwg337: yes
   struct B { virtual ~B() = 0; };
 }
 
+// cwg338: dup 1884
+
 namespace cwg339 { // cwg339: 2.8
   template <int I> struct A { static const int value = I; };
 
diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html
index 6640ed477a241e..186f7cc0ace546 100755
--- a/clang/www/cxx_dr_status.html
+++ b/clang/www/cxx_dr_status.html
@@ -1721,7 +1721,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
     <td><a href="https://cplusplus.github.io/CWG/issues/279.html">279</a></td>
     <td>CD6</td>
     <td>Correspondence of "names for linkage purposes"</td>
-    <td class="unknown" align="center">Unknown</td>
+    <td class="none" align="center">No</td>
   </tr>
   <tr id="280">
     <td><a href="https://cplusplus.github.io/CWG/issues/280.html">280</a></td>
@@ -2075,7 +2075,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
     <td><a href="https://cplusplus.github.io/CWG/issues/338.html">338</a></td>
     <td>CD6</td>
     <td>Enumerator name with linkage used as class name in other translation unit</td>
-    <td class="unknown" align="center">Unknown</td>
+    <td class="partial" align="center">Duplicate of <a href="#1884">1884</a></td>
   </tr>
   <tr id="339">
     <td><a href="https://cplusplus.github.io/CWG/issues/339.html">339</a></td>
@@ -11131,7 +11131,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
     <td><a href="https://cplusplus.github.io/CWG/issues/1884.html">1884</a></td>
     <td>CD6</td>
     <td>Unclear requirements for same-named external-linkage entities</td>
-    <td class="unknown" align="center">Unknown</td>
+    <td class="partial" align="center">Partial</td>
   </tr>
   <tr id="1885">
     <td><a href="https://cplusplus.github.io/CWG/issues/1885.html">1885</a></td>

>From 4d081aaa93088539cde8b7c21ec6866a5ed83b2a Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sat, 26 Oct 2024 19:57:09 +0300
Subject: [PATCH 2/5] Add another case to CWG279 test

---
 clang/test/CXX/drs/cwg279.cpp | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/clang/test/CXX/drs/cwg279.cpp b/clang/test/CXX/drs/cwg279.cpp
index 3f3782b79ebff8..3c63486cc0dd5e 100644
--- a/clang/test/CXX/drs/cwg279.cpp
+++ b/clang/test/CXX/drs/cwg279.cpp
@@ -19,6 +19,9 @@ extern S *q; // #cwg279-q
 
 struct S2 {}; // #cwg279-S2
 extern S2 *q2; // #cwg279-q2
+
+struct S3 {}; // #cwg279-S3
+extern S3 *q3; // #cwg279-q3
 } // export
 
 //--- cwg279.cpp
@@ -40,3 +43,11 @@ typedef struct {} S2;
 extern S2 *q2;
 // since-cxx20-error at -1 {{declaration of 'q2' in the global module follows declaration in module cwg279_A}}
 //   since-cxx20-note at cwg279_A.cppm:21 {{previous declaration is here}}
+
+// FIXME: This is well-formed, because [basic.def.odr]/15 is satisfied.
+struct S3 {};
+// since-cxx20-error at -1 {{redefinition of 'S3'}}
+//   since-cxx20-note at cwg279_A.cppm:23 {{previous definition is here}}
+extern S3 *q3;
+// since-cxx20-error at -1 {{declaration of 'q3' in the global module follows declaration in module cwg279_A}}
+//   since-cxx20-note at cwg279_A.cppm:24 {{previous declaration is here}}

>From 70c24fc2dd9d991417495c130583c3bf30452071 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sun, 27 Oct 2024 00:23:07 +0300
Subject: [PATCH 3/5] Clarify what we need to fix to claim full conformance to
 CWG1884

---
 clang/test/CXX/drs/cwg1884.cpp | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/clang/test/CXX/drs/cwg1884.cpp b/clang/test/CXX/drs/cwg1884.cpp
index d8fa9c4373765c..bec7dde22be440 100644
--- a/clang/test/CXX/drs/cwg1884.cpp
+++ b/clang/test/CXX/drs/cwg1884.cpp
@@ -255,6 +255,8 @@ enum Ee {
 namespace e {} // #cwg1884-namespace-e
 // since-cxx20-error at -1 {{redefinition of 'e' as different kind of symbol}}
 //   since-cxx20-note@#cwg1884-int-e {{previous definition is here}}
+// FIXME: the following forward declaration is well-formed.
+//        Agreement on class-key is not required per [dcl.type.elab]/7.
 class e;
 // since-cxx20-error at -1 {{declaration of 'e' in the global module follows declaration in module cwg1884_A}}
 //   since-cxx20-note at cwg1884_A.cppm:46 {{previous declaration is here}}
@@ -300,6 +302,8 @@ enum Ef {
 namespace f {} // #cwg1884-namespace-f
 // since-cxx20-error at -1 {{redefinition of 'f' as different kind of symbol}}
 //   since-cxx20-note@#cwg1884-int-f {{previous definition is here}}
+// FIXME: the following forward declaration is well-formed.
+//        Agreement on class-key is not required per [dcl.type.elab]/7.
 struct f;
 // since-cxx20-error at -1 {{declaration of 'f' in the global module follows declaration in module cwg1884_A}}
 //   since-cxx20-note at cwg1884_A.cppm:47 {{previous declaration is here}}
@@ -377,6 +381,8 @@ concept g = true;
 // template <typename>
 // void h(int);
 
+// FIXME: we don't diagnose several cases we should be. They are marked with MISSING prefix.
+
 int h;
 // since-cxx20-error at -1 {{redefinition of 'h' as different kind of symbol}}
 //   since-cxx20-note at cwg1884_A.cppm:51 {{previous definition is here}}
@@ -384,12 +390,12 @@ void h(); // #cwg1884-function-f
 // @-1 OK, a non-corresponding overload
 enum Eh {
   h
-  // FIXME-since-cxx20-error at -1 {{redefinition of 'h'}}
-  //   FIXME-since-cxx20-note at cwg1884_A.cppm:51 {{previous definition is here}}
+  // MISSING-since-cxx20-error at -1 {{redefinition of 'h'}}
+  //   MISSING-since-cxx20-note at cwg1884_A.cppm:51 {{previous definition is here}}
 };
 namespace h {} // #cwg1884-namespace-h
-// FIXME-since-cxx20-error at -1 {{redefinition of 'h' as different kind of symbol}}
-//   FIXME-since-cxx20-note at cwg1884_A.cppm:51 {{previous definition is here}}
+// MISSING-since-cxx20-error at -1 {{redefinition of 'h' as different kind of symbol}}
+//   MISSING-since-cxx20-note at cwg1884_A.cppm:51 {{previous definition is here}}
 struct h;
 // since-cxx20-error at -1 {{redefinition of 'h' as different kind of symbol}}
 //   since-cxx20-note@#cwg1884-namespace-h {{previous definition is here}}
@@ -398,8 +404,8 @@ class h;
 //   since-cxx20-note@#cwg1884-namespace-h {{previous definition is here}}
 template <typename>
 class h;
-// FIXME-since-cxx20-error at -1 {{redefinition of 'h' as different kind of symbol}}
-//   FIXME-since-cxx20-note at cwg1884_A.cppm:51 {{previous definition is here}}
+// MISSING-since-cxx20-error at -1 {{redefinition of 'h' as different kind of symbol}}
+//   MISSING-since-cxx20-note at cwg1884_A.cppm:51 {{previous definition is here}}
 template <typename, typename>
 int h;
 // since-cxx20-error at -1 {{redefinition of 'h' as different kind of symbol}}

>From d0f7cbcefed00dc4ecd25b85e6dd7c9fed0ceb9c Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Mon, 28 Oct 2024 13:01:54 +0300
Subject: [PATCH 4/5] Major update: improve isolation of the individual cases

---
 clang/test/CXX/drs/cwg1884.cpp | 925 ++++++++++++++++++---------------
 1 file changed, 507 insertions(+), 418 deletions(-)

diff --git a/clang/test/CXX/drs/cwg1884.cpp b/clang/test/CXX/drs/cwg1884.cpp
index bec7dde22be440..fe35a77f7ef283 100644
--- a/clang/test/CXX/drs/cwg1884.cpp
+++ b/clang/test/CXX/drs/cwg1884.cpp
@@ -31,7 +31,7 @@
 // No diagnostic is required if neither declaration is reachable from the other.
 
 // The structure of the test is the following. First, module cwg1884_A
-// provides all (significant) kinds of entities, each named 'a' through 'k'.
+// provides all (significant) kinds of entities, each named 'a' through 'h', and copies of them.
 // Then the .cpp file does MxN kind of testing, where it tests one kind of entity
 // against every other kind.
 
@@ -39,516 +39,605 @@
 export module cwg1884_A;
 
 export {
-int a;
-void b();
-enum E { c };
-namespace d {}
-struct e;
-class f;
+int a1;
+int a2;
+int a3;
+int a4;
+int a5;
+int a6;
+int a7;
+int a8;
+int a9;
+int a10;
+int a11;
+void b1();
+void b2();
+void b3();
+void b4();
+void b5();
+void b6();
+void b7();
+void b8();
+void b9();
+void b10();
+void b11();
+enum E {
+  c1,
+  c2, 
+  c3,
+  c4,
+  c5,
+  c6,
+  c7,
+  c8,
+  c9,
+  c10
+};
+namespace d1 {}
+namespace d2 {}
+namespace d3 {}
+namespace d4 {}
+namespace d5 {}
+namespace d6 {}
+namespace d7 {}
+namespace d8 {}
+namespace d9 {}
+namespace d10 {}
+struct e1;
+struct e2;
+struct e3;
+struct e4;
+struct e5;
+struct e6;
+struct e7;
+struct e8;
+struct e9;
+struct e10;
+struct e11;
+struct e12;
+struct e13;
+template <typename>
+class f1;
+template <typename>
+class f2;
+template <typename>
+class f3;
+template <typename>
+class f4;
+template <typename>
+class f5;
+template <typename>
+class f6;
+template <typename>
+class f7;
+template <typename>
+class f8;
+template <typename>
+class f9;
+template <typename>
+class f10;
+template <typename>
+class f11;
+template <typename>
+void g1(int);
+template <typename>
+void g2(int);
+template <typename>
+void g3(int);
+template <typename>
+void g4(int);
+template <typename>
+void g5(int);
+template <typename>
+void g6(int);
+template <typename>
+void g7(int);
+template <typename>
+void g8(int);
 template <typename>
-class g;
+void g9(int);
 template <typename>
-void h(int);
+void g10(int);
 template <typename, typename>
-int i;
+int h1;
+template <typename, typename>
+int h2;
+template <typename, typename>
+int h3;
+template <typename, typename>
+int h4;
+template <typename, typename>
+int h5;
+template <typename, typename>
+int h6;
+template <typename, typename>
+int h7;
+template <typename, typename>
+int h8;
+template <typename, typename>
+int h9;
+template <typename, typename>
+int h10;
+template <typename>
+using i1 = int;
+template <typename>
+using i2 = int;
+template <typename>
+using i3 = int;
+template <typename>
+using i4 = int;
+template <typename>
+using i5 = int;
+template <typename>
+using i6 = int;
+template <typename>
+using i7 = int;
+template <typename>
+using i8 = int;
+template <typename>
+using i9 = int;
+template <typename>
+using i10 = int;
+template <typename>
+using i11 = int;
 template <typename>
-using j = int;
+concept j1 = true;
 template <typename>
-concept k = true;
+concept j2 = true;
+template <typename>
+concept j3 = true;
+template <typename>
+concept j4 = true;
+template <typename>
+concept j5 = true;
+template <typename>
+concept j6 = true;
+template <typename>
+concept j7 = true;
+template <typename>
+concept j8 = true;
+template <typename>
+concept j9 = true;
+template <typename>
+concept j10 = true;
+template <typename>
+concept j11 = true;
 } // export
 
 
 //--- cwg1884.cpp
 import cwg1884_A;
 
-// int a;
+// FIXME: we don't diagnose several cases we should be. They are marked with MISSING prefix.
+
+// Part A: matching against `int a;`
+// ---------------------------------
 
-void a();
-// since-cxx20-error at -1 {{redefinition of 'a' as different kind of symbol}}
+void a1();
+// since-cxx20-error at -1 {{redefinition of 'a1' as different kind of symbol}}
 //   since-cxx20-note at cwg1884_A.cppm:42 {{previous definition is here}}
 enum Ea {
-  a
-  // since-cxx20-error at -1 {{redefinition of 'a'}}
-  //   since-cxx20-note at cwg1884_A.cppm:42 {{previous definition is here}}
+  a2
+  // since-cxx20-error at -1 {{redefinition of 'a2'}}
+  //   since-cxx20-note at cwg1884_A.cppm:43 {{previous definition is here}}
 };
-namespace a {} // #cwg1884-namespace-a
-// since-cxx20-error at -1 {{redefinition of 'a' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:42 {{previous definition is here}}
-struct a;
-// since-cxx20-error at -1 {{redefinition of 'a' as different kind of symbol}}
-//   since-cxx20-note@#cwg1884-namespace-a {{previous definition is here}}
-class a;
-// since-cxx20-error at -1 {{redefinition of 'a' as different kind of symbol}}
-//   since-cxx20-note@#cwg1884-namespace-a {{previous definition is here}}
-template <typename>
-class a;
-// since-cxx20-error at -1 {{redefinition of 'a' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:42 {{previous definition is here}}
+namespace a3 {}
+// since-cxx20-error at -1 {{redefinition of 'a3' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:44 {{previous definition is here}}
+struct a4;
+// @-1 OK, types and variables do not correspond
 template <typename>
-void a(int);
-// since-cxx20-error at -1 {{redefinition of 'a' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:42 {{previous definition is here}}
+class a5;
+// since-cxx20-error at -1 {{redefinition of 'a5' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:46 {{previous definition is here}}
+template <typename>
+void a6(int);
+// since-cxx20-error at -1 {{redefinition of 'a6' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:47 {{previous definition is here}}
 template <typename, typename>
-int a;
-// since-cxx20-error at -1 {{redefinition of 'a' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:42 {{previous definition is here}}
+int a7;
+// since-cxx20-error at -1 {{redefinition of 'a7' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:48 {{previous definition is here}}
 template <typename T>
-int a<T, int>;
-// since-cxx20-error at -1 {{redefinition of 'a' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:42 {{previous definition is here}}
+int a8<T, int>;
+// since-cxx20-error at -1 {{redefinition of 'a8' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:49 {{previous definition is here}}
 // since-cxx20-error at -3 {{expected ';' after top level declarator}}
 template <typename>
-using a = int;
-// since-cxx20-error at -1 {{redefinition of 'a' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:42 {{previous definition is here}}
+using a9 = int;
+// since-cxx20-error at -1 {{redefinition of 'a9' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:50 {{previous definition is here}}
 template <typename>
-concept a = true;
-// since-cxx20-error at -1 {{redefinition of 'a' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:42 {{previous definition is here}}
+concept a10 = true;
+// since-cxx20-error at -1 {{redefinition of 'a10' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:51 {{previous definition is here}}
+// For variables, type has to match as well.
+long a11;
+// since-cxx20-error at -1 {{redefinition of 'a11' with a different type: 'long' vs 'int'}}
+//   since-cxx20-note at cwg1884_A.cppm:52 {{previous definition is here}}
 
 
-// void b();
+// Part B: matching against `void b();`
+// ------------------------------------
 
-int b;
-// since-cxx20-error at -1 {{redefinition of 'b' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:43 {{previous definition is here}}
+int b1;
+// since-cxx20-error at -1 {{redefinition of 'b1' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:53 {{previous definition is here}}
 enum Eb {
-  b
-  // since-cxx20-error at -1 {{redefinition of 'b'}}
-  //   since-cxx20-note at cwg1884_A.cppm:43 {{previous definition is here}}
+  b2
+  // since-cxx20-error at -1 {{redefinition of 'b2'}}
+  //   since-cxx20-note at cwg1884_A.cppm:54 {{previous definition is here}}
 };
-namespace b {} // #cwg1884-namespace-b
-// since-cxx20-error at -1 {{redefinition of 'b' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:43 {{previous definition is here}}
-struct b;
-// since-cxx20-error at -1 {{redefinition of 'b' as different kind of symbol}}
-//   since-cxx20-note@#cwg1884-namespace-b {{previous definition is here}}
-class b;
-// since-cxx20-error at -1 {{redefinition of 'b' as different kind of symbol}}
-//   since-cxx20-note@#cwg1884-namespace-b {{previous definition is here}}
-template <typename>
-class b;
-// since-cxx20-error at -1 {{redefinition of 'b' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:43 {{previous definition is here}}
-template <typename>
-void b(int); // #cwg1884-func-template-b
+namespace b3 {} // #cwg1884-namespace-b
+// since-cxx20-error at -1 {{redefinition of 'b3' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:55 {{previous definition is here}}
+struct b4;
+// @-1 OK, types and functions do not correspond
+template <typename>
+class b5;
+// since-cxx20-error at -1 {{redefinition of 'b5' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:57 {{previous definition is here}}
+template <typename>
+void b6(int);
 // @-1 OK, a non-corresponding overload
 template <typename, typename>
-int b;
-// since-cxx20-error at -1 {{redefinition of 'b' as different kind of symbol}}
-//   since-cxx20-note@#cwg1884-func-template-b {{previous definition is here}}
+int b7;
+// since-cxx20-error at -1 {{redefinition of 'b7' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:59 {{previous definition is here}}
 template <typename T>
-int b<T, int>;
-// since-cxx20-error at -1 {{no variable template matches specialization; did you mean to use 'b' as function template instead?}}
-template <typename>
-using b = int;
-// since-cxx20-error at -1 {{redefinition of 'b' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:43 {{previous definition is here}}
-template <typename>
-concept b = true;
-// since-cxx20-error at -1 {{redefinition of 'b' as different kind of symbol}}
-//   since-cxx20-note@#cwg1884-func-template-b {{previous definition is here}}
-
-
-// enum E { c };
-
-int c;
-// since-cxx20-error at -1 {{redefinition of 'c' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:44 {{previous definition is here}}
-void c();
-// since-cxx20-error at -1 {{redefinition of 'c' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:44 {{previous definition is here}}
-namespace c {} // #cwg1884-namespace-c
-// since-cxx20-error at -1 {{redefinition of 'c' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:44 {{previous definition is here}}
-struct c;
-// since-cxx20-error at -1 {{redefinition of 'c' as different kind of symbol}}
-//   since-cxx20-note@#cwg1884-namespace-c {{previous definition is here}}
-class c;
-// since-cxx20-error at -1 {{redefinition of 'c' as different kind of symbol}}
-//   since-cxx20-note@#cwg1884-namespace-c {{previous definition is here}}
-template <typename>
-class c;
-// since-cxx20-error at -1 {{redefinition of 'c' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:44 {{previous definition is here}}
+int b8<T, int>;
+// since-cxx20-error at -1 {{no variable template matches partial specialization}}
 template <typename>
-void c(int);
-// since-cxx20-error at -1 {{redefinition of 'c' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:44 {{previous definition is here}}
+using b9 = int;
+// since-cxx20-error at -1 {{redefinition of 'b9' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:61 {{previous definition is here}}
+template <typename>
+concept b10 = true;
+// since-cxx20-error at -1 {{redefinition of 'b10' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:62 {{previous definition is here}}
+// For functions, type has to match as well.
+// FIXME: we should be loud and clear here about type mismatch, like we do in `a11` case.
+int b11();
+// since-cxx20-error at -1 {{declaration of 'b11' in the global module follows declaration in module cwg1884_A}}
+//   since-cxx20-note at cwg1884_A.cppm:63 {{previous declaration is here}}
+
+
+// Part C: matching against `enum E { c };`
+// ----------------------------------------
+
+int c1;
+// since-cxx20-error at -1 {{redefinition of 'c1' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:65 {{previous definition is here}}
+void c2();
+// since-cxx20-error at -1 {{redefinition of 'c2' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:66 {{previous definition is here}}
+namespace c3 {}
+// since-cxx20-error at -1 {{redefinition of 'c3' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:67 {{previous definition is here}}
+struct c4;
+// @-1 OK, types and enumerators do not correspond
+template <typename>
+class c5;
+// since-cxx20-error at -1 {{redefinition of 'c5' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:69 {{previous definition is here}}
+template <typename>
+void c6(int);
+// since-cxx20-error at -1 {{redefinition of 'c6' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:70 {{previous definition is here}}
 template <typename, typename>
-int c;
-// since-cxx20-error at -1 {{redefinition of 'c' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:44 {{previous definition is here}}
+int c7;
+// since-cxx20-error at -1 {{redefinition of 'c7' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:71 {{previous definition is here}}
 template <typename T>
-int c<T, int>;
-// since-cxx20-error at -1 {{redefinition of 'c' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:44 {{previous definition is here}}
+int c8<T, int>;
+// since-cxx20-error at -1 {{redefinition of 'c8' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:72 {{previous definition is here}}
 // since-cxx20-error at -3 {{expected ';' after top level declarator}}
 template <typename>
-using c = int;
-// since-cxx20-error at -1 {{redefinition of 'c' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:44 {{previous definition is here}}
+using c9 = int;
+// since-cxx20-error at -1 {{redefinition of 'c9' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:73 {{previous definition is here}}
 template <typename>
-concept c = true;
-// since-cxx20-error at -1 {{redefinition of 'c' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:44 {{previous definition is here}}
+concept c10 = true;
+// since-cxx20-error at -1 {{redefinition of 'c10' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:74 {{previous definition is here}}
 
 
-// namespace d {};
+// Part D: matching against `namespace d {};`
+// ------------------------------------------
 
-int d;
-// since-cxx20-error at -1 {{redefinition of 'd' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:45 {{previous definition is here}}
-void d();
-// since-cxx20-error at -1 {{redefinition of 'd' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:45 {{previous definition is here}}
+int d1;
+// since-cxx20-error at -1 {{redefinition of 'd1' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:76 {{previous definition is here}}
+void d2();
+// since-cxx20-error at -1 {{redefinition of 'd2' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:77 {{previous definition is here}}
 enum Ed {
-  d
-  // since-cxx20-error at -1 {{redefinition of 'd'}}
-  //   since-cxx20-note at cwg1884_A.cppm:45 {{previous definition is here}}
+  d3
+  // since-cxx20-error at -1 {{redefinition of 'd3'}}
+  //   since-cxx20-note at cwg1884_A.cppm:78 {{previous definition is here}}
 };
-struct d;
-// since-cxx20-error at -1 {{redefinition of 'd' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:45 {{previous definition is here}}
-class d;
-// since-cxx20-error at -1 {{redefinition of 'd' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:45 {{previous definition is here}}
-template <typename>
-class d;
-// since-cxx20-error at -1 {{redefinition of 'd' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:45 {{previous definition is here}}
-template <typename>
-void d(int);
-// since-cxx20-error at -1 {{redefinition of 'd' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:45 {{previous definition is here}}
+struct d4;
+// since-cxx20-error at -1 {{redefinition of 'd4' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:79 {{previous definition is here}}
+template <typename>
+class d5;
+// since-cxx20-error at -1 {{redefinition of 'd5' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:80 {{previous definition is here}}
+template <typename>
+void d6(int);
+// since-cxx20-error at -1 {{redefinition of 'd6' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:81 {{previous definition is here}}
 template <typename, typename>
-int d;
-// since-cxx20-error at -1 {{redefinition of 'd' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:45 {{previous definition is here}}
+int d7;
+// since-cxx20-error at -1 {{redefinition of 'd7' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:82 {{previous definition is here}}
 template <typename T>
-int d<T, int>;
-// since-cxx20-error at -1 {{redefinition of 'd' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:45 {{previous definition is here}}
+int d8<T, int>;
+// since-cxx20-error at -1 {{redefinition of 'd8' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:83 {{previous definition is here}}
 // since-cxx20-error at -3 {{expected ';' after top level declarator}}
 template <typename>
-using d = int;
-// since-cxx20-error at -1 {{redefinition of 'd' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:45 {{previous definition is here}}
+using d9 = int;
+// since-cxx20-error at -1 {{redefinition of 'd9' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:84 {{previous definition is here}}
 template <typename>
-concept d = true;
-// since-cxx20-error at -1 {{redefinition of 'd' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:45 {{previous definition is here}}
+concept d10 = true;
+// since-cxx20-error at -1 {{redefinition of 'd10' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:85 {{previous definition is here}}
 
 
-// struct e;
+// Part E: matching against `struct e;`
+// ------------------------------------
 
-int e; // #cwg1884-int-e
+int e1;
 // @-1 OK, types and variables do not correspond
-void e();
-// since-cxx20-error at -1 {{redefinition of 'e' as different kind of symbol}}
-//   since-cxx20-note@#cwg1884-int-e {{previous definition is here}}
+void e2();
+// @-1 OK, types and functions do not correspond
 enum Ee {
-  e
-  // since-cxx20-error at -1 {{redefinition of 'e'}}
-  //   since-cxx20-note@#cwg1884-int-e {{previous definition is here}}
+  e3
+  // @-1 OK, types and enumerators do not correspond
 };
-namespace e {} // #cwg1884-namespace-e
-// since-cxx20-error at -1 {{redefinition of 'e' as different kind of symbol}}
-//   since-cxx20-note@#cwg1884-int-e {{previous definition is here}}
-// FIXME: the following forward declaration is well-formed.
-//        Agreement on class-key is not required per [dcl.type.elab]/7.
-class e;
-// since-cxx20-error at -1 {{declaration of 'e' in the global module follows declaration in module cwg1884_A}}
-//   since-cxx20-note at cwg1884_A.cppm:46 {{previous declaration is here}}
-template <typename>
-class e;
-// since-cxx20-error at -1 {{redefinition of 'e' as different kind of symbol}}
-//   since-cxx20-note@#cwg1884-int-e {{previous definition is here}}
-template <typename>
-void e(int);
-// since-cxx20-error at -1 {{redefinition of 'e' as different kind of symbol}}
-//   since-cxx20-note@#cwg1884-int-e {{previous definition is here}}
-template <typename, typename>
-int e;
-// since-cxx20-error at -1 {{redefinition of 'e' as different kind of symbol}}
-//   since-cxx20-note@#cwg1884-int-e {{previous definition is here}}
-template <typename T>
-int e<T, int>;
-// since-cxx20-error at -1 {{redefinition of 'e' as different kind of symbol}}
-//   since-cxx20-note@#cwg1884-int-e {{previous definition is here}}
-// since-cxx20-error at -3 {{expected ';' after top level declarator}}
+namespace e4 {}
+// since-cxx20-error at -1 {{redefinition of 'e4' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:89 {{previous definition is here}}
 template <typename>
-using e = int;
-// since-cxx20-error at -1 {{redefinition of 'e' as different kind of symbol}}
-//   since-cxx20-note@#cwg1884-int-e {{previous definition is here}}
+class e5;
+// since-cxx20-error at -1 {{redefinition of 'e5' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:90 {{previous definition is here}}
 template <typename>
-concept e = true;
-// since-cxx20-error at -1 {{redefinition of 'e' as different kind of symbol}}
-//   since-cxx20-note@#cwg1884-int-e {{previous definition is here}}
-
-
-// class f;
-
-int f; // #cwg1884-int-f
-// @-1 OK, types and variables do not correspond
-void f();
-// since-cxx20-error at -1 {{redefinition of 'f' as different kind of symbol}}
-//   since-cxx20-note@#cwg1884-int-f {{previous definition is here}}
-enum Ef {
-  f
-  // since-cxx20-error at -1 {{redefinition of 'f'}}
-  //   since-cxx20-note@#cwg1884-int-f {{previous definition is here}}
-};
-namespace f {} // #cwg1884-namespace-f
-// since-cxx20-error at -1 {{redefinition of 'f' as different kind of symbol}}
-//   since-cxx20-note@#cwg1884-int-f {{previous definition is here}}
-// FIXME: the following forward declaration is well-formed.
-//        Agreement on class-key is not required per [dcl.type.elab]/7.
-struct f;
-// since-cxx20-error at -1 {{declaration of 'f' in the global module follows declaration in module cwg1884_A}}
-//   since-cxx20-note at cwg1884_A.cppm:47 {{previous declaration is here}}
-template <typename>
-class f;
-// since-cxx20-error at -1 {{redefinition of 'f' as different kind of symbol}}
-//   since-cxx20-note@#cwg1884-int-f {{previous definition is here}}
-template <typename>
-void f(int);
-// since-cxx20-error at -1 {{redefinition of 'f' as different kind of symbol}}
-//   since-cxx20-note@#cwg1884-int-f {{previous definition is here}}
+void e6(int);
+// @-1 OK, types and function templates do not correspond
 template <typename, typename>
-int f;
-// since-cxx20-error at -1 {{redefinition of 'f' as different kind of symbol}}
-//   since-cxx20-note@#cwg1884-int-f {{previous definition is here}}
+int e7;
+// since-cxx20-error at -1 {{redefinition of 'e7' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:92 {{previous definition is here}}
 template <typename T>
-int f<T, int>;
-// since-cxx20-error at -1 {{redefinition of 'f' as different kind of symbol}}
-//   since-cxx20-note@#cwg1884-int-f {{previous definition is here}}
+int e8<T, int>;
+// since-cxx20-error at -1 {{redefinition of 'e8' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:93 {{previous definition is here}}
 // since-cxx20-error at -3 {{expected ';' after top level declarator}}
 template <typename>
-using f = int;
-// since-cxx20-error at -1 {{redefinition of 'f' as different kind of symbol}}
-//   since-cxx20-note@#cwg1884-int-f {{previous definition is here}}
+using e9 = int;
+// since-cxx20-error at -1 {{redefinition of 'e9' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:94 {{previous definition is here}}
 template <typename>
-concept f = true;
-// since-cxx20-error at -1 {{redefinition of 'f' as different kind of symbol}}
-//   since-cxx20-note@#cwg1884-int-f {{previous definition is here}}
-
-
-// template <typename>
-// class g;
-
-int g;
-// since-cxx20-error at -1 {{redefinition of 'g' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:49 {{previous definition is here}}
-void g();
-// since-cxx20-error at -1 {{redefinition of 'g' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:49 {{previous definition is here}}
-enum Eg {
-  g
-  // since-cxx20-error at -1 {{redefinition of 'g'}}
-  //   since-cxx20-note at cwg1884_A.cppm:49 {{previous definition is here}}
+concept e10 = true;
+// since-cxx20-error at -1 {{redefinition of 'e10' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:95 {{previous definition is here}}
+// FIXME: the following forward declaration is well-formed.
+//        Agreement on 'struct' vs 'class' is not required per [dcl.type.elab]/7.
+class e11;
+// since-cxx20-error at -1 {{declaration of 'e11' in the global module follows declaration in module cwg1884_A}}
+//   since-cxx20-note at cwg1884_A.cppm:96 {{previous declaration is here}}
+union e12;
+// since-cxx20-error at -1 {{use of 'e12' with tag type that does not match previous declaration}}
+//   since-cxx20-note at cwg1884_A.cppm:97 {{previous use is here}}
+// since-cxx20-error at -3 {{declaration of 'e12' in the global module follows declaration in module cwg1884_A}}
+//   since-cxx20-note at cwg1884_A.cppm:97 {{previous declaration is here}}
+enum e13 {};
+// since-cxx20-error at -1 {{use of 'e13' with tag type that does not match previous declaration}}
+//   since-cxx20-note at cwg1884_A.cppm:98 {{previous use is here}}
+
+
+// Part F: matching against `template <typename> class f;`
+// -------------------------------------------------------
+
+int f1;
+// since-cxx20-error at -1 {{redefinition of 'f1' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:100 {{previous definition is here}}
+void f2();
+// since-cxx20-error at -1 {{redefinition of 'f2' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:102 {{previous definition is here}}
+enum Ef {
+  f3
+  // since-cxx20-error at -1 {{redefinition of 'f3'}}
+  //   since-cxx20-note at cwg1884_A.cppm:104 {{previous definition is here}}
 };
-namespace g {}
-// since-cxx20-error at -1 {{redefinition of 'g' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:49 {{previous definition is here}}
-struct g;
-// since-cxx20-error at -1 {{redefinition of 'g' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:49 {{previous definition is here}}
-class g;
-// since-cxx20-error at -1 {{redefinition of 'g' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:49 {{previous definition is here}}
-template <typename>
-void g(int);
-// since-cxx20-error at -1 {{redefinition of 'g' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:49 {{previous definition is here}}
+namespace f4 {}
+// since-cxx20-error at -1 {{redefinition of 'f4' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:106 {{previous definition is here}}
+struct f5;
+// since-cxx20-error at -1 {{redefinition of 'f5' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:108 {{previous definition is here}}
+template <typename>
+void f6(int);
+// since-cxx20-error at -1 {{redefinition of 'f6' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:110 {{previous definition is here}}
 template <typename, typename>
-int g;
-// since-cxx20-error at -1 {{redefinition of 'g' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:49 {{previous definition is here}}
+int f7;
+// since-cxx20-error at -1 {{redefinition of 'f7' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:112 {{previous definition is here}}
 template <typename T>
-int g<T, int>;
+int f8<T, int>;
 // since-cxx20-error at -1 {{no variable template matches partial specialization}}
 template <typename>
-using g = int;
-// since-cxx20-error at -1 {{redefinition of 'g' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:49 {{previous definition is here}}
+using f9 = int;
+// since-cxx20-error at -1 {{redefinition of 'f9' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:116 {{previous definition is here}}
 template <typename>
-concept g = true;
-// since-cxx20-error at -1 {{redefinition of 'g' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:49 {{previous definition is here}}
+concept f10 = true;
+// since-cxx20-error at -1 {{redefinition of 'f10' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:118 {{previous definition is here}}
 
 
-// template <typename>
-// void h(int);
+// Part G: matching against `template <typename> void g(int);`
+// -----------------------------------------------------------
 
-// FIXME: we don't diagnose several cases we should be. They are marked with MISSING prefix.
-
-int h;
-// since-cxx20-error at -1 {{redefinition of 'h' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:51 {{previous definition is here}}
-void h(); // #cwg1884-function-f
+int g1;
+// since-cxx20-error at -1 {{redefinition of 'g1' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:122 {{previous definition is here}}
+void g2();
 // @-1 OK, a non-corresponding overload
-enum Eh {
-  h
-  // MISSING-since-cxx20-error at -1 {{redefinition of 'h'}}
-  //   MISSING-since-cxx20-note at cwg1884_A.cppm:51 {{previous definition is here}}
+enum Eg {
+  g3
+  // MISSING-since-cxx20-error at -1 {{redefinition of 'g3'}}
+  //   MISSING-since-cxx20-note at cwg1884_A.cppm:126 {{previous definition is here}}
 };
-namespace h {} // #cwg1884-namespace-h
-// MISSING-since-cxx20-error at -1 {{redefinition of 'h' as different kind of symbol}}
-//   MISSING-since-cxx20-note at cwg1884_A.cppm:51 {{previous definition is here}}
-struct h;
-// since-cxx20-error at -1 {{redefinition of 'h' as different kind of symbol}}
-//   since-cxx20-note@#cwg1884-namespace-h {{previous definition is here}}
-class h;
-// since-cxx20-error at -1 {{redefinition of 'h' as different kind of symbol}}
-//   since-cxx20-note@#cwg1884-namespace-h {{previous definition is here}}
-template <typename>
-class h;
-// MISSING-since-cxx20-error at -1 {{redefinition of 'h' as different kind of symbol}}
-//   MISSING-since-cxx20-note at cwg1884_A.cppm:51 {{previous definition is here}}
+namespace g4 {}
+// MISSING-since-cxx20-error at -1 {{redefinition of 'g4' as different kind of symbol}}
+//   MISSING-since-cxx20-note at cwg1884_A.cppm:128 {{previous definition is here}}
+struct g5;
+// @-1 OK, types and function templates do not correspond
+template <typename>
+class g6;
+// since-cxx20-error at -1 {{redefinition of 'g6' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:132 {{previous definition is here}}
 template <typename, typename>
-int h;
-// since-cxx20-error at -1 {{redefinition of 'h' as different kind of symbol}}
-//   since-cxx20-note@#cwg1884-namespace-h {{previous definition is here}}
+int g7;
+// since-cxx20-error at -1 {{redefinition of 'g7' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:134 {{previous definition is here}}
 template <typename T>
-int h<T, int>;
-// since-cxx20-error at -1 {{no variable template matches specialization; did you mean to use 'h' as function template instead?}}
+int g8<T, int>;
+// since-cxx20-error at -1 {{no variable template matches specialization; did you mean to use 'g8' as function template instead?}}
 template <typename>
-using h = int;
-// since-cxx20-error at -1 {{redefinition of 'h' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:51 {{previous definition is here}}
+using g9 = int;
+// since-cxx20-error at -1 {{redefinition of 'g9' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:138 {{previous definition is here}}
 template <typename>
-concept h = true;
-// since-cxx20-error at -1 {{redefinition of 'h' as different kind of symbol}}
-//   since-cxx20-note@#cwg1884-function-f {{previous definition is here}}
+concept g10 = true;
+// since-cxx20-error at -1 {{redefinition of 'g10' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:140 {{previous definition is here}}
 
 
-// template <typename, typename>
-// int i;
+// Part H: matching against `template <typename, typename> int h;`
+// ---------------------------------------------------------------
 
-int i;
-// since-cxx20-error at -1 {{redefinition of 'i' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:53 {{previous definition is here}}
-void i();
-// since-cxx20-error at -1 {{redefinition of 'i' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:53 {{previous definition is here}}
-enum Ei {
-  i
-  // since-cxx20-error at -1 {{redefinition of 'i'}}
-  //   since-cxx20-note at cwg1884_A.cppm:53 {{previous definition is here}}
+int h1;
+// since-cxx20-error at -1 {{redefinition of 'h1' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:142 {{previous definition is here}}
+void h2();
+// since-cxx20-error at -1 {{redefinition of 'h2' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:144 {{previous definition is here}}
+enum Eh {
+  h3
+  // since-cxx20-error at -1 {{redefinition of 'h3'}}
+  //   since-cxx20-note at cwg1884_A.cppm:146 {{previous definition is here}}
 };
-namespace i {}
-// since-cxx20-error at -1 {{redefinition of 'i' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:53 {{previous definition is here}}
-struct i;
-// since-cxx20-error at -1 {{redefinition of 'i' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:53 {{previous definition is here}}
-class i;
-// since-cxx20-error at -1 {{redefinition of 'i' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:53 {{previous definition is here}}
-template <typename>
-class i;
-// since-cxx20-error at -1 {{redefinition of 'i' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:53 {{previous definition is here}}
-template <typename>
-void i(int);
-// since-cxx20-error at -1 {{redefinition of 'i' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:53 {{previous definition is here}}
+namespace h4 {}
+// since-cxx20-error at -1 {{redefinition of 'h4' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:148 {{previous definition is here}}
+struct h5;
+// since-cxx20-error at -1 {{redefinition of 'h5' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:150 {{previous definition is here}}
+template <typename>
+class h6;
+// since-cxx20-error at -1 {{redefinition of 'h6' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:152 {{previous definition is here}}
+template <typename>
+void h7(int);
+// since-cxx20-error at -1 {{redefinition of 'h7' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:154 {{previous definition is here}}
 template <typename T>
-int i<T, int>; // OK, partial specialization
+int h8<T, int>;
+// @-1 OK, partial specialization
 template <typename>
-using i = int;
-// since-cxx20-error at -1 {{redefinition of 'i' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:53 {{previous definition is here}}
+using h9 = int;
+// since-cxx20-error at -1 {{redefinition of 'h9' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:158 {{previous definition is here}}
 template <typename>
-concept i = true;
-// since-cxx20-error at -1 {{redefinition of 'i' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:53 {{previous definition is here}}
+concept h10 = true;
+// since-cxx20-error at -1 {{redefinition of 'h10' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:160 {{previous definition is here}}
 
 
-// template <typename>
-// using j = int;
+// Part I: matching against `template <typename> using i = int;`
+// -------------------------------------------------------------
 
-int j;
-// since-cxx20-error at -1 {{redefinition of 'j' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:55 {{previous definition is here}}
-void j();
-// since-cxx20-error at -1 {{redefinition of 'j' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:55 {{previous definition is here}}
-enum Ej {
-  j
-  // since-cxx20-error at -1 {{redefinition of 'j'}}
-  //   since-cxx20-note at cwg1884_A.cppm:55 {{previous definition is here}}
+int i1;
+// since-cxx20-error at -1 {{redefinition of 'i1' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:162 {{previous definition is here}}
+void i2();
+// since-cxx20-error at -1 {{redefinition of 'i2' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:164 {{previous definition is here}}
+enum Ei {
+  i3
+  // since-cxx20-error at -1 {{redefinition of 'i3'}}
+  //   since-cxx20-note at cwg1884_A.cppm:166 {{previous definition is here}}
 };
-namespace j {}
-// since-cxx20-error at -1 {{redefinition of 'j' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:55 {{previous definition is here}}
-struct j;
-// since-cxx20-error at -1 {{redefinition of 'j' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:55 {{previous definition is here}}
-class j;
-// since-cxx20-error at -1 {{redefinition of 'j' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:55 {{previous definition is here}}
-template <typename>
-class j;
-// since-cxx20-error at -1 {{redefinition of 'j' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:55 {{previous definition is here}}
-template <typename>
-void j(int);
-// since-cxx20-error at -1 {{redefinition of 'j' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:55 {{previous definition is here}}
+namespace i4 {}
+// since-cxx20-error at -1 {{redefinition of 'i4' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:168 {{previous definition is here}}
+struct i5;
+// since-cxx20-error at -1 {{redefinition of 'i5' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:170 {{previous definition is here}}
+template <typename>
+class i6;
+// since-cxx20-error at -1 {{redefinition of 'i6' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:172 {{previous definition is here}}
+template <typename>
+void i7(int);
+// since-cxx20-error at -1 {{redefinition of 'i7' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:174 {{previous definition is here}}
 template <typename, typename>
-int j;
-// since-cxx20-error at -1 {{redefinition of 'j' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:55 {{previous definition is here}}
+int i8;
+// since-cxx20-error at -1 {{redefinition of 'i8' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:176 {{previous definition is here}}
 template <typename T>
-int j<T, int>;
+int i9<T, int>;
 // since-cxx20-error at -1 {{no variable template matches partial specialization}}
 template <typename>
-concept j = true;
-// since-cxx20-error at -1 {{redefinition of 'j' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:55 {{previous definition is here}}
+concept i10 = true;
+// since-cxx20-error at -1 {{redefinition of 'i10' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:180 {{previous definition is here}}
 
 
-// template <typename>
-// concept k = true;
+// Part J: matching against `template <typename> concept j = true;`
+// ----------------------------------------------------------------
 
-int k;
-// since-cxx20-error at -1 {{redefinition of 'k' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:57 {{previous definition is here}}
-void k();
-// since-cxx20-error at -1 {{redefinition of 'k' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:57 {{previous definition is here}}
-enum Ek {
-  k
-  // since-cxx20-error at -1 {{redefinition of 'k'}}
-  //   since-cxx20-note at cwg1884_A.cppm:57 {{previous definition is here}}
+int j1;
+// since-cxx20-error at -1 {{redefinition of 'j1' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:184 {{previous definition is here}}
+void j2();
+// since-cxx20-error at -1 {{redefinition of 'j2' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:186 {{previous definition is here}}
+enum Ej {
+  j3
+  // since-cxx20-error at -1 {{redefinition of 'j3'}}
+  //   since-cxx20-note at cwg1884_A.cppm:188 {{previous definition is here}}
 };
-namespace k {}
-// since-cxx20-error at -1 {{redefinition of 'k' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:57 {{previous definition is here}}
-struct k;
-// since-cxx20-error at -1 {{redefinition of 'k' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:57 {{previous definition is here}}
-class k;
-// since-cxx20-error at -1 {{redefinition of 'k' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:57 {{previous definition is here}}
-template <typename>
-class k;
-// since-cxx20-error at -1 {{redefinition of 'k' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:57 {{previous definition is here}}
-template <typename>
-void k(int);
-// since-cxx20-error at -1 {{redefinition of 'k' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:57 {{previous definition is here}}
+namespace j4 {}
+// since-cxx20-error at -1 {{redefinition of 'j4' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:190 {{previous definition is here}}
+struct j5;
+// since-cxx20-error at -1 {{redefinition of 'j5' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:192 {{previous definition is here}}
+template <typename>
+class j6;
+// since-cxx20-error at -1 {{redefinition of 'j6' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:194 {{previous definition is here}}
+template <typename>
+void j7(int);
+// since-cxx20-error at -1 {{redefinition of 'j7' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:196 {{previous definition is here}}
 template <typename, typename>
-int k;
-// since-cxx20-error at -1 {{redefinition of 'k' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:57 {{previous definition is here}}
+int j8;
+// since-cxx20-error at -1 {{redefinition of 'j8' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:198 {{previous definition is here}}
 template <typename T>
-int k<T, int>;
+int j9<T, int>;
 // since-cxx20-error at -1 {{no variable template matches partial specialization}}
 template <typename>
-using k = int;
-// since-cxx20-error at -1 {{redefinition of 'k' as different kind of symbol}}
-//   since-cxx20-note at cwg1884_A.cppm:57 {{previous definition is here}}
+using j10 = int;
+// since-cxx20-error at -1 {{redefinition of 'j10' as different kind of symbol}}
+//   since-cxx20-note at cwg1884_A.cppm:202 {{previous definition is here}}

>From 3a1ce0d3f5463c84048297dd36a43a0c8d6ecbc4 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Mon, 28 Oct 2024 13:05:53 +0300
Subject: [PATCH 5/5] Add a comment about partial availability

---
 clang/test/CXX/drs/cwg1884.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/test/CXX/drs/cwg1884.cpp b/clang/test/CXX/drs/cwg1884.cpp
index fe35a77f7ef283..c4f76baa3933fb 100644
--- a/clang/test/CXX/drs/cwg1884.cpp
+++ b/clang/test/CXX/drs/cwg1884.cpp
@@ -9,6 +9,7 @@
 // RUN: %clang_cc1 -std=c++2c -verify=since-cxx20 -pedantic-errors -fexceptions -fcxx-exceptions -triple x86_64-unknown-unknown %t/cwg1884.cpp -fmodule-file=cwg1884_A=%t/cwg1884_A.pcm
 
 // cwg1884: partial
+// Cases b11, e11, g3, g4 are problematic, but we handle the other 101 cases fine.
 
 // _N4993_.[basic.link]/11:
 // For any two declarations of an entity E:
@@ -32,8 +33,7 @@
 
 // The structure of the test is the following. First, module cwg1884_A
 // provides all (significant) kinds of entities, each named 'a' through 'h', and copies of them.
-// Then the .cpp file does MxN kind of testing, where it tests one kind of entity
-// against every other kind.
+// Then the .cpp file does MxN kind of testing, where it tests one kind of entity against every other kind.
 
 //--- cwg1884_A.cppm
 export module cwg1884_A;



More information about the cfe-commits mailing list