[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
Sat Oct 26 09:58:39 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/2] [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/2] 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}}



More information about the cfe-commits mailing list