From fc89e9044d0b37dcd4e3f085f21bef1b21d2ab8d Mon Sep 17 00:00:00 2001 From: Chuanqi Xu Date: Thu, 18 May 2023 16:11:20 +0800 Subject: [PATCH] [C++20] [Modules] Emit an warning for experimental header units Currently, the header units are rarely used and it is not well tested. To avoid further misunderstandings, let's mark it as experimental and emit a warning when users wants to import it. This is discussed in modules developers meeting. --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 4 ++++ clang/lib/Sema/SemaModule.cpp | 3 +++ clang/test/CXX/module/module.interface/p2.cpp | 5 +++-- clang/test/Modules/cxx20-10-2-ex2.cpp | 2 +- clang/test/Modules/cxx20-hu-04.cpp | 6 +++--- clang/test/Modules/cxx20-include-translation.cpp | 5 +++-- clang/test/Modules/merge-concepts.cppm | 6 ++---- 7 files changed, 19 insertions(+), 12 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 0d93727..54671bf 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -11279,6 +11279,10 @@ def err_invalid_module_name : Error<"%0 is an invalid name for a module">; def err_extern_def_in_header_unit : Error< "non-inline external definitions are not permitted in C++ header units">; +def warn_experimental_header_unit : Warning< + "the implementation of header units is in an experimental phase">, + InGroup>; + def ext_equivalent_internal_linkage_decl_in_modules : ExtWarn< "ambiguous use of internal linkage declaration %0 defined in multiple modules">, InGroup>; diff --git a/clang/lib/Sema/SemaModule.cpp b/clang/lib/Sema/SemaModule.cpp index e1d7c29..a1ab013 100644 --- a/clang/lib/Sema/SemaModule.cpp +++ b/clang/lib/Sema/SemaModule.cpp @@ -544,6 +544,9 @@ DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc, SourceLocation ExportLoc, SourceLocation ImportLoc, Module *Mod, ModuleIdPath Path) { + if (Mod->isHeaderUnit()) + Diag(ImportLoc, diag::warn_experimental_header_unit); + VisibleModules.setVisible(Mod, ImportLoc); checkModuleImportContext(*this, Mod, ImportLoc, CurContext); diff --git a/clang/test/CXX/module/module.interface/p2.cpp b/clang/test/CXX/module/module.interface/p2.cpp index 0cb6514..bf4e3f9 100644 --- a/clang/test/CXX/module/module.interface/p2.cpp +++ b/clang/test/CXX/module/module.interface/p2.cpp @@ -5,9 +5,10 @@ // RUN: %clang_cc1 -std=c++20 %s -DY_INTERFACE -emit-module-interface -o %t/y.pcm // RUN: %clang_cc1 -std=c++20 %s -DINTERFACE -fmodule-file=X=%t/x.pcm -fmodule-file=Y=%t/y.pcm -emit-module-interface -o %t/m.pcm // RUN: %clang_cc1 -std=c++20 %s -DIMPLEMENTATION -I%S/Inputs -fmodule-file=%t/h.pcm \ -// RUN: -fmodule-file=X=%t/x.pcm -fmodule-file=Y=%t/y.pcm -fmodule-file=p2=%t/m.pcm -verify +// RUN: -fmodule-file=X=%t/x.pcm -fmodule-file=Y=%t/y.pcm -fmodule-file=p2=%t/m.pcm -verify \ +// RUN: -Wno-experimental-header-units // RUN: %clang_cc1 -std=c++20 %s -DUSER -I%S/Inputs -fmodule-file=%t/h.pcm -fmodule-file=p2=%t/m.pcm \ -// RUN: -fmodule-file=X=%t/x.pcm -fmodule-file=Y=%t/y.pcm -verify +// RUN: -fmodule-file=X=%t/x.pcm -fmodule-file=Y=%t/y.pcm -Wno-experimental-header-units -verify #if defined(X_INTERFACE) export module X; diff --git a/clang/test/Modules/cxx20-10-2-ex2.cpp b/clang/test/Modules/cxx20-10-2-ex2.cpp index 659e4fe..bc66d6a 100644 --- a/clang/test/Modules/cxx20-10-2-ex2.cpp +++ b/clang/test/Modules/cxx20-10-2-ex2.cpp @@ -29,7 +29,7 @@ module; #include "std-10-2-ex2-b.h" export module M; -import "std-10-2-ex2-c.h"; +import "std-10-2-ex2-c.h"; // expected-warning {{the implementation of header units is in an experimental phase}} import X; export using ::f, ::g, ::h; // OK struct S; // expected-note {{target of using declaration}} diff --git a/clang/test/Modules/cxx20-hu-04.cpp b/clang/test/Modules/cxx20-hu-04.cpp index da6056d..aed1bdb 100644 --- a/clang/test/Modules/cxx20-hu-04.cpp +++ b/clang/test/Modules/cxx20-hu-04.cpp @@ -42,7 +42,7 @@ int baz(int); // CHECK-HU-NEXT: Header Unit './hu-01.h' is the Primary Module at index #1 //--- hu-02.h -export import "hu-01.h"; +export import "hu-01.h"; // expected-warning {{the implementation of header units is in an experimental phase}} #if !defined(FORTYTWO) || FORTYTWO != 42 #error FORTYTWO missing in hu-02 #endif @@ -82,7 +82,7 @@ inline int bar(int x) { //--- importer-01.cpp export module B; -import "hu-02.h"; +import "hu-02.h"; // expected-warning {{the implementation of header units is in an experimental phase}} int success(int x) { return foo(FORTYTWO + x + KAP); @@ -95,7 +95,7 @@ int fail(int x) { //--- importer-02.cpp export module C; -import "hu-02.h"; +import "hu-02.h"; // expected-warning {{the implementation of header units is in an experimental phase}} int success(int x) { return foo(FORTYTWO + x + KAP); diff --git a/clang/test/Modules/cxx20-include-translation.cpp b/clang/test/Modules/cxx20-include-translation.cpp index 32c7439..2528e83 100644 --- a/clang/test/Modules/cxx20-include-translation.cpp +++ b/clang/test/Modules/cxx20-include-translation.cpp @@ -80,16 +80,17 @@ void five(); module /*nothing here*/; // This should be include-translated, when the header unit for h1 is available. + // expected-warning@+1 {{the implementation of header units is in an experimental phase}} #include "h1.h" // expected-remark {{treating #include as an import of module './h1.h'}} // Import of a header unit is allowed, named modules are not. -import "h2.h"; +import "h2.h"; // expected-warning {{the implementation of header units is in an experimental phase}} // A regular, untranslated, header #include "h5.h" export module Xlate; // This is OK, the import immediately follows the module decl. -import "h3.h"; +import "h3.h"; // expected-warning {{the implementation of header units is in an experimental phase}} // This should *not* be include-translated, even if header unit for h4 is // available. diff --git a/clang/test/Modules/merge-concepts.cppm b/clang/test/Modules/merge-concepts.cppm index ca4877b..9b611bc 100644 --- a/clang/test/Modules/merge-concepts.cppm +++ b/clang/test/Modules/merge-concepts.cppm @@ -143,8 +143,7 @@ concept same_as = __is_same(T, U); // expected-note@* 1+{{previous definition is here}} //--- Use5.cpp -// expected-no-diagnostics -import "foo.h"; +import "foo.h"; // expected-warning {{the implementation of header units is in an experimental phase}} import A; template void foo() @@ -152,9 +151,8 @@ template void foo() {} //--- Use6.cpp -// expected-no-diagnostics import A; -import "foo.h"; +import "foo.h"; // expected-warning {{the implementation of header units is in an experimental phase}} template void foo() requires same_as -- 2.7.4