[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