From 99f02a874984f2b79c3fbd8ae6bbceb7366521ad Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov Date: Wed, 4 Sep 2024 05:35:13 +0400 Subject: [PATCH] [clang] Add tests for CWG issues about language linkage (#107019) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch covers Core issues about language linkage during declaration matching resolved in [P1787R6](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1787r6.html), namely [CWG563](https://cplusplus.github.io/CWG/issues/563.html) and [CWG1818](https://cplusplus.github.io/CWG/issues/1818.html). [CWG563](https://cplusplus.github.io/CWG/issues/563.html) "Linkage specification for objects" ----------- [P1787R6](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1787r6.html): > [CWG563](https://cplusplus.github.io/CWG/issues/563.html) is resolved by simplifications that follow its suggestions. Wording ([[dcl.link]/5](https://eel.is/c++draft/dcl.link#5)): > In a [linkage-specification](https://eel.is/c++draft/dcl.link#nt:linkage-specification), the specified language linkage applies to the function types of all function declarators and to all functions and variables whose names have external linkage[.](https://eel.is/c++draft/dcl.link#5.sentence-5) Now the wording clearly says that linkage-specification applies to variables with external linkage. [CWG1818](https://cplusplus.github.io/CWG/issues/1818.html) "Visibility and inherited language linkage" ------------ [P1787R6](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1787r6.html): > [CWG386](http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#386), [CWG1839](http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1839), [CWG1818](http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1818), [CWG2058](http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2058), [CWG1900](http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1900), and Richard’s observation in [“are non-type names ignored in a class-head-name or enum-head-name?”](http://lists.isocpp.org/core/2017/01/1604.php) are resolved by describing the limited lookup that occurs for a declarator-id, including the changes in Richard’s [proposed resolution for CWG1839](http://wiki.edg.com/pub/Wg21cologne2019/CoreWorkingGroup/cwg1839.html) (which also resolves CWG1818 and what of CWG2058 was not resolved along with CWG2059) and rejecting the example from [CWG1477](http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1477). Wording ([[dcl.link]/6](https://eel.is/c++draft/dcl.link#6)): > A redeclaration of an entity without a linkage specification inherits the language linkage of the entity and (if applicable) its type[.](https://eel.is/c++draft/dcl.link#6.sentence-2). Answer to the question in the example is `extern "C"`, and not linkage mismatch. Further analysis of the example is provided as inline comments in the test itself. Note that https://eel.is/c++draft/dcl.link#7 does NOT apply in this example, as it's focused squarely at declarations that are already known to have C language linkage, and declarations of variables in the global scope. --- clang/test/CXX/drs/cwg1818.cpp | 34 ++++++++++++++++++++++++++++++++++ clang/test/CXX/drs/cwg18xx.cpp | 2 ++ clang/test/CXX/drs/cwg563.cpp | 16 ++++++++++++++++ clang/test/CXX/drs/cwg5xx.cpp | 1 + clang/www/cxx_dr_status.html | 4 ++-- 5 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 clang/test/CXX/drs/cwg1818.cpp create mode 100644 clang/test/CXX/drs/cwg563.cpp diff --git a/clang/test/CXX/drs/cwg1818.cpp b/clang/test/CXX/drs/cwg1818.cpp new file mode 100644 index 00000000000000..bf2d12696a729c --- /dev/null +++ b/clang/test/CXX/drs/cwg1818.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -std=c++98 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s +// RUN: %clang_cc1 -std=c++11 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s +// RUN: %clang_cc1 -std=c++14 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s +// RUN: %clang_cc1 -std=c++17 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s +// RUN: %clang_cc1 -std=c++20 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s +// RUN: %clang_cc1 -std=c++23 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s +// RUN: %clang_cc1 -std=c++2c %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s + +// expected-no-diagnostics + +namespace cwg1818 { // cwg1818: 3.4 +extern "C" void f() { + // This declaration binds name 'g' in the scope of function 'f', + // but its target scope corresponds to namespace 'cwg1818' (_N4988_.[dcl.meaning]/3.5). + // Linkage specification of 'f' applies to 'g' per _N4988_.[dcl.link]/5. + void g(); +} +// Target scope of this declaration is naturally the one +// that corresponds to namespace 'cwg1818', +// which makes it declare the same entity +// as the previous declaration per _N4988_.[basic.link]/8, +// turning it into a redeclaration per _N4988_.[basic.def]/1. +// Then _N4988_.[dcl.link]/6 applies, making it inherit +// the (С) language linkage of the previous declaration. +void g(); +} // namespace cwg1818 + +// Check that the former 'g' has C language linkage, +// then that the latter 'g' is considered to be a redeclaration of it, +// which would make the latter 'g' inherit C language linkage from the former 'g'. + +// CHECK: LinkageSpecDecl [[LINKAGE_DECL:0x[0-9a-f]+]] {{.*}} C +// CHECK: FunctionDecl [[FIRST_DECL:0x[0-9a-f]+]] parent [[LINKAGE_DECL]] {{.*}} g 'void ()' +// CHECK: FunctionDecl {{.*}} prev [[FIRST_DECL]] {{.*}} g 'void ()' diff --git a/clang/test/CXX/drs/cwg18xx.cpp b/clang/test/CXX/drs/cwg18xx.cpp index adfdb738e81c9e..61b7faa96a9fbb 100644 --- a/clang/test/CXX/drs/cwg18xx.cpp +++ b/clang/test/CXX/drs/cwg18xx.cpp @@ -222,6 +222,8 @@ namespace cwg1815 { // cwg1815: no #endif } +// cwg1818 is in cwg1818.cpp + namespace cwg1820 { // cwg1820: 3.5 typedef int A; typedef int cwg1820::A; diff --git a/clang/test/CXX/drs/cwg563.cpp b/clang/test/CXX/drs/cwg563.cpp new file mode 100644 index 00000000000000..d585fefc44ffce --- /dev/null +++ b/clang/test/CXX/drs/cwg563.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -std=c++98 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s +// RUN: %clang_cc1 -std=c++11 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s +// RUN: %clang_cc1 -std=c++14 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s +// RUN: %clang_cc1 -std=c++17 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s +// RUN: %clang_cc1 -std=c++20 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s +// RUN: %clang_cc1 -std=c++23 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s +// RUN: %clang_cc1 -std=c++2c %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s + +// expected-no-diagnostics + +namespace cwg563 { // cwg563: 3.3 +extern "C" int a; +} // namespace cwg563 + +// CHECK: LinkageSpecDecl {{.*}} C +// CHECK-NEXT: `-VarDecl {{.*}} a 'int' diff --git a/clang/test/CXX/drs/cwg5xx.cpp b/clang/test/CXX/drs/cwg5xx.cpp index 6a0bb7a1966693..ed0c7159dfc889 100644 --- a/clang/test/CXX/drs/cwg5xx.cpp +++ b/clang/test/CXX/drs/cwg5xx.cpp @@ -799,6 +799,7 @@ namespace cwg561 { // cwg561: yes } // cwg562: na +// cwg563 is in cwg563.cpp namespace cwg564 { // cwg564: yes extern "C++" void f(int); diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html index ca25776823cfa5..aa79c3706f32bf 100755 --- a/clang/www/cxx_dr_status.html +++ b/clang/www/cxx_dr_status.html @@ -3431,7 +3431,7 @@

C++ defect report implementation status

563 CD6 Linkage specification for objects - Unknown + Clang 3.3 564 @@ -10735,7 +10735,7 @@

C++ defect report implementation status

1818 CD6 Visibility and inherited language linkage - Unknown + Clang 3.4 1819